iew_impl.hh revision 2292
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29// @todo: Fix the instantaneous communication among all the stages within 30// iew. There's a clear delay between issue and execute, yet backwards 31// communication happens simultaneously. 32 33#include <queue> 34 35#include "base/timebuf.hh" 36#include "cpu/o3/fu_pool.hh" 37#include "cpu/o3/iew.hh" 38 39using namespace std; 40 41template<class Impl> 42DefaultIEW<Impl>::LdWritebackEvent::LdWritebackEvent(DynInstPtr &_inst, 43 DefaultIEW<Impl> *_iew) 44 : Event(&mainEventQueue), inst(_inst), iewStage(_iew) 45{ 46 this->setFlags(Event::AutoDelete); 47} 48 49template<class Impl> 50void 51DefaultIEW<Impl>::LdWritebackEvent::process() 52{ 53 DPRINTF(IEW, "Load writeback event [sn:%lli]\n", inst->seqNum); 54 DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum); 55 56 //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum); 57 58 iewStage->wakeCPU(); 59 60 if (inst->isSquashed()) { 61 inst = NULL; 62 return; 63 } 64 65 if (!inst->isExecuted()) { 66 inst->setExecuted(); 67 68 // Execute again to copy data to proper place. 69 if (inst->isStore()) { 70 inst->completeAcc(); 71 } 72 } 73 74 // Need to insert instruction into queue to commit 75 iewStage->instToCommit(inst); 76 77 //wroteToTimeBuffer = true; 78 iewStage->activityThisCycle(); 79 80 inst = NULL; 81} 82 83template<class Impl> 84const char * 85DefaultIEW<Impl>::LdWritebackEvent::description() 86{ 87 return "Load writeback event"; 88} 89 90template<class Impl> 91DefaultIEW<Impl>::DefaultIEW(Params *params) 92 : // Just make this time buffer really big for now 93 // @todo: Make this into a parameter. 94 issueToExecQueue(5, 5), 95 instQueue(params), 96 ldstQueue(params), 97 fuPool(params->fuPool), 98 commitToIEWDelay(params->commitToIEWDelay), 99 renameToIEWDelay(params->renameToIEWDelay), 100 issueToExecuteDelay(params->issueToExecuteDelay), 101 issueReadWidth(params->issueWidth), 102 issueWidth(params->issueWidth), 103 executeWidth(params->executeWidth), 104 numThreads(params->numberOfThreads) 105{ 106 DPRINTF(IEW, "executeIntWidth: %i.\n", params->executeIntWidth); 107 _status = Active; 108 exeStatus = Running; 109 wbStatus = Idle; 110 111 // Setup wire to read instructions coming from issue. 112 fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay); 113 114 // Instruction queue needs the queue between issue and execute. 115 instQueue.setIssueToExecuteQueue(&issueToExecQueue); 116 117 instQueue.setIEW(this); 118 ldstQueue.setIEW(this); 119 120 for (int i=0; i < numThreads; i++) { 121 dispatchStatus[i] = Running; 122 stalls[i].commit = false; 123 fetchRedirect[i] = false; 124 } 125 126 updateLSQNextCycle = false; 127 128 // @todo: Make into a parameter 129 skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth; 130} 131 132template <class Impl> 133std::string 134DefaultIEW<Impl>::name() const 135{ 136 return cpu->name() + ".iew"; 137} 138 139template <class Impl> 140void 141DefaultIEW<Impl>::regStats() 142{ 143 instQueue.regStats(); 144 145 //ldstQueue.regStats(); 146 147 iewIdleCycles 148 .name(name() + ".iewIdleCycles") 149 .desc("Number of cycles IEW is idle"); 150 151 iewSquashCycles 152 .name(name() + ".iewSquashCycles") 153 .desc("Number of cycles IEW is squashing"); 154 155 iewBlockCycles 156 .name(name() + ".iewBlockCycles") 157 .desc("Number of cycles IEW is blocking"); 158 159 iewUnblockCycles 160 .name(name() + ".iewUnblockCycles") 161 .desc("Number of cycles IEW is unblocking"); 162 163// iewWBInsts; 164 165 iewDispatchedInsts 166 .name(name() + ".iewDispatchedInsts") 167 .desc("Number of instructions dispatched to IQ"); 168 169 iewDispSquashedInsts 170 .name(name() + ".iewDispSquashedInsts") 171 .desc("Number of squashed instructions skipped by dispatch"); 172 173 iewDispLoadInsts 174 .name(name() + ".iewDispLoadInsts") 175 .desc("Number of dispatched load instructions"); 176 177 iewDispStoreInsts 178 .name(name() + ".iewDispStoreInsts") 179 .desc("Number of dispatched store instructions"); 180 181 iewDispNonSpecInsts 182 .name(name() + ".iewDispNonSpecInsts") 183 .desc("Number of dispatched non-speculative instructions"); 184 185 iewIQFullEvents 186 .name(name() + ".iewIQFullEvents") 187 .desc("Number of times the IQ has become full, causing a stall"); 188 189 iewLSQFullEvents 190 .name(name() + ".iewLSQFullEvents") 191 .desc("Number of times the LSQ has become full, causing a stall"); 192 193 iewExecutedInsts 194 .name(name() + ".iewExecutedInsts") 195 .desc("Number of executed instructions"); 196 197 iewExecLoadInsts 198 .name(name() + ".iewExecLoadInsts") 199 .desc("Number of load instructions executed"); 200 201 iewExecStoreInsts 202 .name(name() + ".iewExecStoreInsts") 203 .desc("Number of store instructions executed"); 204 205 iewExecSquashedInsts 206 .name(name() + ".iewExecSquashedInsts") 207 .desc("Number of squashed instructions skipped in execute"); 208 209 memOrderViolationEvents 210 .name(name() + ".memOrderViolationEvents") 211 .desc("Number of memory order violations"); 212 213 predictedTakenIncorrect 214 .name(name() + ".predictedTakenIncorrect") 215 .desc("Number of branches that were predicted taken incorrectly"); 216 217 predictedNotTakenIncorrect 218 .name(name() + ".predictedNotTakenIncorrect") 219 .desc("Number of branches that were predicted not taken incorrectly"); 220 221 branchMispredicts 222 .name(name() + ".branchMispredicts") 223 .desc("Number of branch mispredicts detected at execute"); 224 225 branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect; 226} 227 228template<class Impl> 229void 230DefaultIEW<Impl>::initStage() 231{ 232 for (int tid=0; tid < numThreads; tid++) { 233 toRename->iewInfo[tid].usedIQ = true; 234 toRename->iewInfo[tid].freeIQEntries = 235 instQueue.numFreeEntries(tid); 236 237 toRename->iewInfo[tid].usedLSQ = true; 238 toRename->iewInfo[tid].freeLSQEntries = 239 ldstQueue.numFreeEntries(tid); 240 } 241} 242 243template<class Impl> 244void 245DefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr) 246{ 247 DPRINTF(IEW, "Setting CPU pointer.\n"); 248 cpu = cpu_ptr; 249 250 instQueue.setCPU(cpu_ptr); 251 ldstQueue.setCPU(cpu_ptr); 252 253 cpu->activateStage(FullCPU::IEWIdx); 254} 255 256template<class Impl> 257void 258DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 259{ 260 DPRINTF(IEW, "Setting time buffer pointer.\n"); 261 timeBuffer = tb_ptr; 262 263 // Setup wire to read information from time buffer, from commit. 264 fromCommit = timeBuffer->getWire(-commitToIEWDelay); 265 266 // Setup wire to write information back to previous stages. 267 toRename = timeBuffer->getWire(0); 268 269 toFetch = timeBuffer->getWire(0); 270 271 // Instruction queue also needs main time buffer. 272 instQueue.setTimeBuffer(tb_ptr); 273} 274 275template<class Impl> 276void 277DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 278{ 279 DPRINTF(IEW, "Setting rename queue pointer.\n"); 280 renameQueue = rq_ptr; 281 282 // Setup wire to read information from rename queue. 283 fromRename = renameQueue->getWire(-renameToIEWDelay); 284} 285 286template<class Impl> 287void 288DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) 289{ 290 DPRINTF(IEW, "Setting IEW queue pointer.\n"); 291 iewQueue = iq_ptr; 292 293 // Setup wire to write instructions to commit. 294 toCommit = iewQueue->getWire(0); 295} 296 297template<class Impl> 298void 299DefaultIEW<Impl>::setActiveThreads(list<unsigned> *at_ptr) 300{ 301 DPRINTF(IEW, "Setting active threads list pointer.\n"); 302 activeThreads = at_ptr; 303 304 ldstQueue.setActiveThreads(at_ptr); 305 instQueue.setActiveThreads(at_ptr); 306} 307 308template<class Impl> 309void 310DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr) 311{ 312 DPRINTF(IEW, "Setting scoreboard pointer.\n"); 313 scoreboard = sb_ptr; 314} 315 316#if 0 317template<class Impl> 318void 319DefaultIEW<Impl>::setPageTable(PageTable *pt_ptr) 320{ 321 ldstQueue.setPageTable(pt_ptr); 322} 323#endif 324 325template<class Impl> 326void 327DefaultIEW<Impl>::squash(unsigned tid) 328{ 329 DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", 330 tid); 331 332 // Tell the IQ to start squashing. 333 instQueue.squash(tid); 334 335 // Tell the LDSTQ to start squashing. 336 ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum,tid); 337 338 updatedQueues = true; 339 340 // Clear the skid buffer in case it has any data in it. 341 while (!skidBuffer[tid].empty()) { 342 343 if (skidBuffer[tid].front()->isLoad() || 344 skidBuffer[tid].front()->isStore() ) { 345 toRename->iewInfo[tid].dispatchedToLSQ++; 346 } 347 348 toRename->iewInfo[tid].dispatched++; 349 350 skidBuffer[tid].pop(); 351 } 352 353 while (!insts[tid].empty()) { 354 if (insts[tid].front()->isLoad() || 355 insts[tid].front()->isStore() ) { 356 toRename->iewInfo[tid].dispatchedToLSQ++; 357 } 358 359 toRename->iewInfo[tid].dispatched++; 360 361 insts[tid].pop(); 362 } 363} 364 365template<class Impl> 366void 367DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid) 368{ 369 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x " 370 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum); 371 372 // Tell rename to squash through the time buffer. 373 toCommit->squash[tid] = true; 374 toCommit->squashedSeqNum[tid] = inst->seqNum; 375 toCommit->mispredPC[tid] = inst->readPC(); 376 toCommit->nextPC[tid] = inst->readNextPC(); 377 toCommit->branchMispredict[tid] = true; 378 // Prediction was incorrect, so send back inverse. 379 toCommit->branchTaken[tid] = inst->readNextPC() != 380 (inst->readPC() + sizeof(TheISA::MachInst)); 381 382 toCommit->includeSquashInst[tid] = false; 383 //toCommit->iewSquashNum[tid] = inst->seqNum; 384 385 wroteToTimeBuffer = true; 386} 387 388template<class Impl> 389void 390DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid) 391{ 392 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, " 393 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 394 395 // Tell rename to squash through the time buffer. 396 toCommit->squash[tid] = true; 397 toCommit->squashedSeqNum[tid] = inst->seqNum; 398 toCommit->nextPC[tid] = inst->readNextPC(); 399 400 toCommit->includeSquashInst[tid] = false; 401 //toCommit->iewSquashNum[tid] = inst->seqNum; 402 403 wroteToTimeBuffer = true; 404} 405 406template<class Impl> 407void 408DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid) 409{ 410 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, " 411 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 412 413 toCommit->squash[tid] = true; 414 toCommit->squashedSeqNum[tid] = inst->seqNum; 415 toCommit->nextPC[tid] = inst->readPC(); 416 417 toCommit->includeSquashInst[tid] = true; 418 419 ldstQueue.setLoadBlockedHandled(tid); 420 421 wroteToTimeBuffer = true; 422} 423 424template<class Impl> 425void 426DefaultIEW<Impl>::block(unsigned tid) 427{ 428 DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid); 429 430 if (dispatchStatus[tid] != Blocked && 431 dispatchStatus[tid] != Unblocking) { 432 toRename->iewBlock[tid] = true; 433 wroteToTimeBuffer = true; 434 } 435 436 // Add the current inputs to the skid buffer so they can be 437 // reprocessed when this stage unblocks. 438 skidInsert(tid); 439 440 // Set the status to Blocked. 441 dispatchStatus[tid] = Blocked; 442} 443 444template<class Impl> 445void 446DefaultIEW<Impl>::unblock(unsigned tid) 447{ 448 DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid " 449 "buffer %u.\n",tid, tid); 450 451 // If the skid bufffer is empty, signal back to previous stages to unblock. 452 // Also switch status to running. 453 if (skidBuffer[tid].empty()) { 454 toRename->iewUnblock[tid] = true; 455 wroteToTimeBuffer = true; 456 DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid); 457 dispatchStatus[tid] = Running; 458 } 459} 460 461template<class Impl> 462void 463DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst) 464{ 465 instQueue.wakeDependents(inst); 466} 467 468template<class Impl> 469void 470DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst) 471{ 472 instQueue.rescheduleMemInst(inst); 473} 474 475template<class Impl> 476void 477DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst) 478{ 479 instQueue.replayMemInst(inst); 480} 481 482template<class Impl> 483void 484DefaultIEW<Impl>::instToCommit(DynInstPtr &inst) 485{ 486 // First check the time slot that this instruction will write 487 // to. If there are free write ports at the time, then go ahead 488 // and write the instruction to that time. If there are not, 489 // keep looking back to see where's the first time there's a 490 // free slot. What happens if you run out of free spaces? 491 // For now naively assume that all instructions take one cycle. 492 // Otherwise would have to look into the time buffer based on the 493 // latency of the instruction. 494 while ((*iewQueue)[wbCycle].insts[wbNumInst]) { 495 ++wbNumInst; 496 if (wbNumInst == issueWidth) { 497 ++wbCycle; 498 wbNumInst = 0; 499 } 500 501 assert(wbCycle < 5); 502 } 503 504 // Add finished instruction to queue to commit. 505 (*iewQueue)[wbCycle].insts[wbNumInst] = inst; 506 (*iewQueue)[wbCycle].size++; 507} 508 509template <class Impl> 510unsigned 511DefaultIEW<Impl>::validInstsFromRename() 512{ 513 unsigned inst_count = 0; 514 515 for (int i=0; i<fromRename->size; i++) { 516 if (!fromRename->insts[i]->squashed) 517 inst_count++; 518 } 519 520 return inst_count; 521} 522 523template<class Impl> 524void 525DefaultIEW<Impl>::skidInsert(unsigned tid) 526{ 527 DynInstPtr inst = NULL; 528 529 while (!insts[tid].empty()) { 530 inst = insts[tid].front(); 531 532 insts[tid].pop(); 533 534 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into " 535 "dispatch skidBuffer %i\n",tid, inst->seqNum, 536 inst->readPC(),tid); 537 538 skidBuffer[tid].push(inst); 539 } 540 541 assert(skidBuffer[tid].size() <= skidBufferMax && 542 "Skidbuffer Exceeded Max Size"); 543} 544 545template<class Impl> 546int 547DefaultIEW<Impl>::skidCount() 548{ 549 int max=0; 550 551 list<unsigned>::iterator threads = (*activeThreads).begin(); 552 553 while (threads != (*activeThreads).end()) { 554 unsigned thread_count = skidBuffer[*threads++].size(); 555 if (max < thread_count) 556 max = thread_count; 557 } 558 559 return max; 560} 561 562template<class Impl> 563bool 564DefaultIEW<Impl>::skidsEmpty() 565{ 566 list<unsigned>::iterator threads = (*activeThreads).begin(); 567 568 while (threads != (*activeThreads).end()) { 569 if (!skidBuffer[*threads++].empty()) 570 return false; 571 } 572 573 return true; 574} 575 576template <class Impl> 577void 578DefaultIEW<Impl>::updateStatus() 579{ 580 bool any_unblocking = false; 581 582 list<unsigned>::iterator threads = (*activeThreads).begin(); 583 584 threads = (*activeThreads).begin(); 585 586 while (threads != (*activeThreads).end()) { 587 unsigned tid = *threads++; 588 589 if (dispatchStatus[tid] == Unblocking) { 590 any_unblocking = true; 591 break; 592 } 593 } 594 595 // If there are no ready instructions waiting to be scheduled by the IQ, 596 // and there's no stores waiting to write back, and dispatch is not 597 // unblocking, then there is no internal activity for the IEW stage. 598 if (_status == Active && !instQueue.hasReadyInsts() && 599 !ldstQueue.willWB() && !any_unblocking) { 600 DPRINTF(IEW, "IEW switching to idle\n"); 601 602 deactivateStage(); 603 604 _status = Inactive; 605 } else if (_status == Inactive && (instQueue.hasReadyInsts() || 606 ldstQueue.willWB() || 607 any_unblocking)) { 608 // Otherwise there is internal activity. Set to active. 609 DPRINTF(IEW, "IEW switching to active\n"); 610 611 activateStage(); 612 613 _status = Active; 614 } 615} 616 617template <class Impl> 618void 619DefaultIEW<Impl>::resetEntries() 620{ 621 instQueue.resetEntries(); 622 ldstQueue.resetEntries(); 623} 624 625template <class Impl> 626void 627DefaultIEW<Impl>::readStallSignals(unsigned tid) 628{ 629 if (fromCommit->commitBlock[tid]) { 630 stalls[tid].commit = true; 631 } 632 633 if (fromCommit->commitUnblock[tid]) { 634 assert(stalls[tid].commit); 635 stalls[tid].commit = false; 636 } 637} 638 639template <class Impl> 640bool 641DefaultIEW<Impl>::checkStall(unsigned tid) 642{ 643 bool ret_val(false); 644 645 if (stalls[tid].commit) { 646 DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid); 647 ret_val = true; 648 } else if (instQueue.isFull(tid)) { 649 DPRINTF(IEW,"[tid:%i]: Stall: IQ is full.\n",tid); 650 ret_val = true; 651 } else if (ldstQueue.isFull(tid)) { 652 DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid); 653 654 if (ldstQueue.numLoads(tid) > 0 ) { 655 656 DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n", 657 tid,ldstQueue.getLoadHeadSeqNum(tid)); 658 } 659 660 if (ldstQueue.numStores(tid) > 0) { 661 662 DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n", 663 tid,ldstQueue.getStoreHeadSeqNum(tid)); 664 } 665 666 ret_val = true; 667 } else if (ldstQueue.isStalled(tid)) { 668 DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid); 669 ret_val = true; 670 } 671 672 return ret_val; 673} 674 675template <class Impl> 676void 677DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid) 678{ 679 // Check if there's a squash signal, squash if there is 680 // Check stall signals, block if there is. 681 // If status was Blocked 682 // if so then go to unblocking 683 // If status was Squashing 684 // check if squashing is not high. Switch to running this cycle. 685 686 readStallSignals(tid); 687 688 if (fromCommit->commitInfo[tid].squash) { 689 squash(tid); 690 691 if (dispatchStatus[tid] == Blocked || 692 dispatchStatus[tid] == Unblocking) { 693 toRename->iewUnblock[tid] = true; 694 wroteToTimeBuffer = true; 695 } 696 697 dispatchStatus[tid] = Squashing; 698 699 fetchRedirect[tid] = false; 700 return; 701 } 702 703 if (fromCommit->commitInfo[tid].robSquashing) { 704 DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n"); 705 706 dispatchStatus[tid] = Squashing; 707 708 return; 709 } 710 711 if (checkStall(tid)) { 712 block(tid); 713 dispatchStatus[tid] = Blocked; 714 return; 715 } 716 717 if (dispatchStatus[tid] == Blocked) { 718 // Status from previous cycle was blocked, but there are no more stall 719 // conditions. Switch over to unblocking. 720 DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n", 721 tid); 722 723 dispatchStatus[tid] = Unblocking; 724 725 unblock(tid); 726 727 return; 728 } 729 730 if (dispatchStatus[tid] == Squashing) { 731 // Switch status to running if rename isn't being told to block or 732 // squash this cycle. 733 DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n", 734 tid); 735 736 dispatchStatus[tid] = Running; 737 738 return; 739 } 740} 741 742template <class Impl> 743void 744DefaultIEW<Impl>::sortInsts() 745{ 746 int insts_from_rename = fromRename->size; 747 748 for (int i = 0; i < numThreads; i++) 749 assert(insts[i].empty()); 750 751 for (int i = 0; i < insts_from_rename; ++i) { 752 insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]); 753 } 754} 755 756template <class Impl> 757void 758DefaultIEW<Impl>::wakeCPU() 759{ 760 cpu->wakeCPU(); 761} 762 763template <class Impl> 764void 765DefaultIEW<Impl>::activityThisCycle() 766{ 767 DPRINTF(Activity, "Activity this cycle.\n"); 768 cpu->activityThisCycle(); 769} 770 771template <class Impl> 772inline void 773DefaultIEW<Impl>::activateStage() 774{ 775 DPRINTF(Activity, "Activating stage.\n"); 776 cpu->activateStage(FullCPU::IEWIdx); 777} 778 779template <class Impl> 780inline void 781DefaultIEW<Impl>::deactivateStage() 782{ 783 DPRINTF(Activity, "Deactivating stage.\n"); 784 cpu->deactivateStage(FullCPU::IEWIdx); 785} 786 787template<class Impl> 788void 789DefaultIEW<Impl>::dispatch(unsigned tid) 790{ 791 // If status is Running or idle, 792 // call dispatchInsts() 793 // If status is Unblocking, 794 // buffer any instructions coming from rename 795 // continue trying to empty skid buffer 796 // check if stall conditions have passed 797 798 if (dispatchStatus[tid] == Blocked) { 799 ++iewBlockCycles; 800 801 } else if (dispatchStatus[tid] == Squashing) { 802 ++iewSquashCycles; 803 } 804 805 // Dispatch should try to dispatch as many instructions as its bandwidth 806 // will allow, as long as it is not currently blocked. 807 if (dispatchStatus[tid] == Running || 808 dispatchStatus[tid] == Idle) { 809 DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run " 810 "dispatch.\n", tid); 811 812 dispatchInsts(tid); 813 } else if (dispatchStatus[tid] == Unblocking) { 814 // Make sure that the skid buffer has something in it if the 815 // status is unblocking. 816 assert(!skidsEmpty()); 817 818 // If the status was unblocking, then instructions from the skid 819 // buffer were used. Remove those instructions and handle 820 // the rest of unblocking. 821 dispatchInsts(tid); 822 823 ++iewUnblockCycles; 824 825 if (validInstsFromRename() && dispatchedAllInsts) { 826 // Add the current inputs to the skid buffer so they can be 827 // reprocessed when this stage unblocks. 828 skidInsert(tid); 829 } 830 831 unblock(tid); 832 } 833} 834 835template <class Impl> 836void 837DefaultIEW<Impl>::dispatchInsts(unsigned tid) 838{ 839 dispatchedAllInsts = true; 840 841 // Obtain instructions from skid buffer if unblocking, or queue from rename 842 // otherwise. 843 std::queue<DynInstPtr> &insts_to_dispatch = 844 dispatchStatus[tid] == Unblocking ? 845 skidBuffer[tid] : insts[tid]; 846 847 int insts_to_add = insts_to_dispatch.size(); 848 849 DynInstPtr inst; 850 bool add_to_iq = false; 851 int dis_num_inst = 0; 852 853 // Loop through the instructions, putting them in the instruction 854 // queue. 855 for ( ; dis_num_inst < insts_to_add && 856 dis_num_inst < issueReadWidth; 857 ++dis_num_inst) 858 { 859 inst = insts_to_dispatch.front(); 860 861 if (dispatchStatus[tid] == Unblocking) { 862 DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid " 863 "buffer\n", tid); 864 } 865 866 // Make sure there's a valid instruction there. 867 assert(inst); 868 869 DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to " 870 "IQ.\n", 871 tid, inst->readPC(), inst->seqNum, inst->threadNumber); 872 873 // Be sure to mark these instructions as ready so that the 874 // commit stage can go ahead and execute them, and mark 875 // them as issued so the IQ doesn't reprocess them. 876 // ------------- 877 // @TODO: What happens if the ldstqueue is full? 878 // Do we process the other instructions? 879 880 // Check for squashed instructions. 881 if (inst->isSquashed()) { 882 DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, " 883 "not adding to IQ.\n", tid); 884 885 ++iewDispSquashedInsts; 886 887 insts_to_dispatch.pop(); 888 889 //Tell Rename That An Instruction has been processed 890 if (inst->isLoad() || inst->isStore()) { 891 toRename->iewInfo[tid].dispatchedToLSQ++; 892 } 893 toRename->iewInfo[tid].dispatched++; 894 895 continue; 896 } 897 898 // Check for full conditions. 899 if (instQueue.isFull(tid)) { 900 DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid); 901 902 // Call function to start blocking. 903 block(tid); 904 905 // Set unblock to false. Special case where we are using 906 // skidbuffer (unblocking) instructions but then we still 907 // get full in the IQ. 908 toRename->iewUnblock[tid] = false; 909 910 dispatchedAllInsts = false; 911 912 ++iewIQFullEvents; 913 break; 914 } else if (ldstQueue.isFull(tid)) { 915 DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid); 916 917 // Call function to start blocking. 918 block(tid); 919 920 // Set unblock to false. Special case where we are using 921 // skidbuffer (unblocking) instructions but then we still 922 // get full in the IQ. 923 toRename->iewUnblock[tid] = false; 924 925 dispatchedAllInsts = false; 926 927 ++iewLSQFullEvents; 928 break; 929 } 930 931 // Otherwise issue the instruction just fine. 932 if (inst->isLoad()) { 933 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 934 "encountered, adding to LSQ.\n", tid); 935 936 // Reserve a spot in the load store queue for this 937 // memory access. 938 ldstQueue.insertLoad(inst); 939 940 ++iewDispLoadInsts; 941 942 add_to_iq = true; 943 944 toRename->iewInfo[tid].dispatchedToLSQ++; 945 } else if (inst->isStore()) { 946 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 947 "encountered, adding to LSQ.\n", tid); 948 949 ldstQueue.insertStore(inst); 950 951 ++iewDispStoreInsts; 952 953 if (inst->isNonSpeculative()) { 954 inst->setCanCommit(); 955 instQueue.insertNonSpec(inst); 956 add_to_iq = false; 957 958 ++iewDispNonSpecInsts; 959 } else { 960 add_to_iq = true; 961 } 962 963 toRename->iewInfo[tid].dispatchedToLSQ++; 964#if FULL_SYSTEM 965 } else if (inst->isMemBarrier() || inst->isWriteBarrier()) { 966 inst->setCanCommit(); 967 instQueue.insertBarrier(inst); 968 add_to_iq = false; 969#endif 970 } else if (inst->isNonSpeculative()) { 971 DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " 972 "encountered, skipping.\n", tid); 973 974 // Same hack as with stores. 975 inst->setCanCommit(); 976 977 // Specifically insert it as nonspeculative. 978 instQueue.insertNonSpec(inst); 979 980 ++iewDispNonSpecInsts; 981 982 add_to_iq = false; 983 } else if (inst->isNop()) { 984 DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, " 985 "skipping.\n", tid); 986 987 inst->setIssued(); 988 inst->setExecuted(); 989 inst->setCanCommit(); 990 991 instQueue.advanceTail(inst); 992 993 add_to_iq = false; 994 } else if (inst->isExecuted()) { 995 assert(0 && "Instruction shouldn't be executed.\n"); 996 DPRINTF(IEW, "Issue: Executed branch encountered, " 997 "skipping.\n"); 998 999 inst->setIssued(); 1000 inst->setCanCommit(); 1001 1002 instQueue.advanceTail(inst); 1003 1004 add_to_iq = false; 1005 } else { 1006 add_to_iq = true; 1007 } 1008 1009 // If the instruction queue is not full, then add the 1010 // instruction. 1011 if (add_to_iq) { 1012 instQueue.insert(inst); 1013 } 1014 1015 insts_to_dispatch.pop(); 1016 1017 toRename->iewInfo[tid].dispatched++; 1018 1019 ++iewDispatchedInsts; 1020 } 1021 1022 if (!insts_to_dispatch.empty()) { 1023 DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n"); 1024 block(tid); 1025 toRename->iewUnblock[tid] = false; 1026 } 1027 1028 if (dispatchStatus[tid] == Idle && dis_num_inst) { 1029 dispatchStatus[tid] = Running; 1030 1031 updatedQueues = true; 1032 } 1033 1034 dis_num_inst = 0; 1035} 1036 1037template <class Impl> 1038void 1039DefaultIEW<Impl>::printAvailableInsts() 1040{ 1041 int inst = 0; 1042 1043 cout << "Available Instructions: "; 1044 1045 while (fromIssue->insts[inst]) { 1046 1047 if (inst%3==0) cout << "\n\t"; 1048 1049 cout << "PC: " << fromIssue->insts[inst]->readPC() 1050 << " TN: " << fromIssue->insts[inst]->threadNumber 1051 << " SN: " << fromIssue->insts[inst]->seqNum << " | "; 1052 1053 inst++; 1054 1055 } 1056 1057 cout << "\n"; 1058} 1059 1060template <class Impl> 1061void 1062DefaultIEW<Impl>::executeInsts() 1063{ 1064 //bool fetch_redirect[(*activeThreads).size()]; 1065 wbNumInst = 0; 1066 wbCycle = 0; 1067 1068 list<unsigned>::iterator threads = (*activeThreads).begin(); 1069 1070 while (threads != (*activeThreads).end()) { 1071 unsigned tid = *threads++; 1072 fetchRedirect[tid] = false; 1073 } 1074 1075#if 0 1076 printAvailableInsts(); 1077#endif 1078 1079 // Execute/writeback any instructions that are available. 1080 int inst_num = 0; 1081 for ( ; inst_num < issueWidth && /* Haven't exceeded issue bandwidth */ 1082 fromIssue->insts[inst_num]; 1083 ++inst_num) { 1084 1085 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n"); 1086 1087 // Get instruction from issue's queue. 1088 DynInstPtr inst = fromIssue->insts[inst_num]; 1089 1090 DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n", 1091 inst->readPC(), inst->threadNumber,inst->seqNum); 1092 1093 // Check if the instruction is squashed; if so then skip it 1094 // and don't count it towards the FU usage. 1095 if (inst->isSquashed()) { 1096 DPRINTF(IEW, "Execute: Instruction was squashed.\n"); 1097 1098 // Consider this instruction executed so that commit can go 1099 // ahead and retire the instruction. 1100 inst->setExecuted(); 1101 1102 // Not sure if I should set this here or just let commit try to 1103 // commit any squashed instructions. I like the latter a bit more. 1104 inst->setCanCommit(); 1105 1106 ++iewExecSquashedInsts; 1107 1108 continue; 1109 } 1110 1111 Fault fault = NoFault; 1112 1113 // Execute instruction. 1114 // Note that if the instruction faults, it will be handled 1115 // at the commit stage. 1116 if (inst->isMemRef() && 1117 (!inst->isDataPrefetch() && !inst->isInstPrefetch())) { 1118 DPRINTF(IEW, "Execute: Calculating address for memory " 1119 "reference.\n"); 1120 1121 // Tell the LDSTQ to execute this instruction (if it is a load). 1122 if (inst->isLoad()) { 1123 // Loads will mark themselves as executed, and their writeback 1124 // event adds the instruction to the queue to commit 1125 fault = ldstQueue.executeLoad(inst); 1126 1127 ++iewExecLoadInsts; 1128 } else if (inst->isStore()) { 1129 ldstQueue.executeStore(inst); 1130 1131 ++iewExecStoreInsts; 1132 1133 // If the store had a fault then it may not have a mem req 1134 if (inst->req && !(inst->req->flags & LOCKED)) { 1135 inst->setExecuted(); 1136 1137 instToCommit(inst); 1138 } 1139 // Store conditionals will mark themselves as executed, and 1140 // their writeback event will add the instruction to the queue 1141 // to commit. 1142 } else { 1143 panic("Unexpected memory type!\n"); 1144 } 1145 1146 } else { 1147 inst->execute(); 1148 1149 ++iewExecutedInsts; 1150 1151 inst->setExecuted(); 1152 1153 instToCommit(inst); 1154 } 1155 1156 // Check if branch was correct. This check happens after the 1157 // instruction is added to the queue because even if the branch 1158 // is mispredicted, the branch instruction itself is still valid. 1159 // Only handle this if there hasn't already been something that 1160 // redirects fetch in this group of instructions. 1161 1162 // This probably needs to prioritize the redirects if a different 1163 // scheduler is used. Currently the scheduler schedules the oldest 1164 // instruction first, so the branch resolution order will be correct. 1165 unsigned tid = inst->threadNumber; 1166 1167 if (!fetchRedirect[tid]) { 1168 1169 if (inst->mispredicted()) { 1170 fetchRedirect[tid] = true; 1171 1172 DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); 1173 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n", 1174 inst->nextPC); 1175 1176 // If incorrect, then signal the ROB that it must be squashed. 1177 squashDueToBranch(inst, tid); 1178 1179 if (inst->predTaken()) { 1180 predictedTakenIncorrect++; 1181 } else { 1182 predictedNotTakenIncorrect++; 1183 } 1184 } else if (ldstQueue.violation(tid)) { 1185 fetchRedirect[tid] = true; 1186 1187 // Get the DynInst that caused the violation. Note that this 1188 // clears the violation signal. 1189 DynInstPtr violator; 1190 violator = ldstQueue.getMemDepViolator(tid); 1191 1192 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " 1193 "%#x, inst PC: %#x. Addr is: %#x.\n", 1194 violator->readPC(), inst->readPC(), inst->physEffAddr); 1195 1196 // Tell the instruction queue that a violation has occured. 1197 instQueue.violation(inst, violator); 1198 1199 // Squash. 1200 squashDueToMemOrder(inst,tid); 1201 1202 ++memOrderViolationEvents; 1203 } else if (ldstQueue.loadBlocked(tid) && 1204 !ldstQueue.isLoadBlockedHandled(tid)) { 1205 fetchRedirect[tid] = true; 1206 1207 DPRINTF(IEW, "Load operation couldn't execute because the " 1208 "memory system is blocked. PC: %#x [sn:%lli]\n", 1209 inst->readPC(), inst->seqNum); 1210 1211 squashDueToMemBlocked(inst, tid); 1212 } 1213 } 1214 } 1215 1216 if (inst_num) { 1217 if (exeStatus == Idle) { 1218 exeStatus = Running; 1219 } 1220 1221 updatedQueues = true; 1222 1223 cpu->activityThisCycle(); 1224 } 1225 1226 // Need to reset this in case a writeback event needs to write into the 1227 // iew queue. That way the writeback event will write into the correct 1228 // spot in the queue. 1229 wbNumInst = 0; 1230} 1231 1232template <class Impl> 1233void 1234DefaultIEW<Impl>::writebackInsts() 1235{ 1236 // Loop through the head of the time buffer and wake any dependents. 1237 // These instructions are about to write back. In the simple model 1238 // this loop can really happen within the previous loop, but when 1239 // instructions have actual latencies, this loop must be separate. 1240 // Also mark scoreboard that this instruction is finally complete. 1241 // Either have IEW have direct access to rename map, or have this as 1242 // part of backwards communication. 1243 for (int inst_num = 0; inst_num < issueWidth && 1244 toCommit->insts[inst_num]; inst_num++) { 1245 DynInstPtr inst = toCommit->insts[inst_num]; 1246 1247 DPRINTF(IEW, "Sending instructions to commit, PC %#x.\n", 1248 inst->readPC()); 1249 1250 // Some instructions will be sent to commit without having 1251 // executed because they need commit to handle them. 1252 // E.g. Uncached loads have not actually executed when they 1253 // are first sent to commit. Instead commit must tell the LSQ 1254 // when it's ready to execute the uncached load. 1255 if (!inst->isSquashed() && inst->isExecuted()) { 1256 instQueue.wakeDependents(inst); 1257 1258 for (int i = 0; i < inst->numDestRegs(); i++) { 1259 //mark as Ready 1260 DPRINTF(IEW,"Setting Destination Register %i\n", 1261 inst->renamedDestRegIdx(i)); 1262 scoreboard->setReg(inst->renamedDestRegIdx(i)); 1263 } 1264 } 1265 } 1266} 1267 1268template<class Impl> 1269void 1270DefaultIEW<Impl>::tick() 1271{ 1272 // Try to fill up issue queue with as many instructions as bandwidth 1273 // allows. 1274 wbNumInst = 0; 1275 wbCycle = 0; 1276 1277 wroteToTimeBuffer = false; 1278 updatedQueues = false; 1279 1280 sortInsts(); 1281 1282 list<unsigned>::iterator threads = (*activeThreads).begin(); 1283 1284 // Check stall and squash signals. 1285 while (threads != (*activeThreads).end()) { 1286 unsigned tid = *threads++; 1287 1288 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid); 1289 1290 checkSignalsAndUpdate(tid); 1291 dispatch(tid); 1292 1293 } 1294 1295 if (exeStatus != Squashing) { 1296 executeInsts(); 1297 1298 writebackInsts(); 1299 1300 // Have the instruction queue try to schedule any ready instructions. 1301 // (In actuality, this scheduling is for instructions that will 1302 // be executed next cycle.) 1303 instQueue.scheduleReadyInsts(); 1304 1305 // Also should advance its own time buffers if the stage ran. 1306 // Not the best place for it, but this works (hopefully). 1307 issueToExecQueue.advance(); 1308 } 1309 1310 bool broadcast_free_entries = false; 1311 1312 if (updatedQueues || exeStatus == Running || updateLSQNextCycle) { 1313 exeStatus = Idle; 1314 updateLSQNextCycle = false; 1315 1316 broadcast_free_entries = true; 1317 } 1318 1319 // Writeback any stores using any leftover bandwidth. 1320 ldstQueue.writebackStores(); 1321 1322 // Free function units marked as being freed this cycle. 1323 fuPool->processFreeUnits(); 1324 1325 // Check the committed load/store signals to see if there's a load 1326 // or store to commit. Also check if it's being told to execute a 1327 // nonspeculative instruction. 1328 // This is pretty inefficient... 1329 1330 threads = (*activeThreads).begin(); 1331 while (threads != (*activeThreads).end()) { 1332 unsigned tid = (*threads++); 1333 1334 DPRINTF(IEW,"Processing [tid:%i]\n",tid); 1335 1336 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 1337 !fromCommit->commitInfo[tid].squash && 1338 !fromCommit->commitInfo[tid].robSquashing) { 1339 1340 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid); 1341 1342 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid); 1343 1344 updateLSQNextCycle = true; 1345 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid); 1346 } 1347 1348 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) { 1349 1350 //DPRINTF(IEW,"NonspecInst from thread %i",tid); 1351 if (fromCommit->commitInfo[tid].uncached) { 1352 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad); 1353 } else { 1354 instQueue.scheduleNonSpec( 1355 fromCommit->commitInfo[tid].nonSpecSeqNum); 1356 } 1357 } 1358 1359 if (broadcast_free_entries) { 1360 toFetch->iewInfo[tid].iqCount = 1361 instQueue.getCount(tid); 1362 toFetch->iewInfo[tid].ldstqCount = 1363 ldstQueue.getCount(tid); 1364 1365 toRename->iewInfo[tid].usedIQ = true; 1366 toRename->iewInfo[tid].freeIQEntries = 1367 instQueue.numFreeEntries(); 1368 toRename->iewInfo[tid].usedLSQ = true; 1369 toRename->iewInfo[tid].freeLSQEntries = 1370 ldstQueue.numFreeEntries(tid); 1371 1372 wroteToTimeBuffer = true; 1373 } 1374 1375 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n", 1376 tid, toRename->iewInfo[tid].dispatched); 1377 1378 //thread_queue.pop(); 1379 } 1380 1381 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). " 1382 "LSQ has %i free entries.\n", 1383 instQueue.numFreeEntries(), instQueue.hasReadyInsts(), 1384 ldstQueue.numFreeEntries()); 1385 1386 updateStatus(); 1387 1388 if (wroteToTimeBuffer) { 1389 DPRINTF(Activity, "Activity this cycle.\n"); 1390 cpu->activityThisCycle(); 1391 } 1392} 1393