iew_impl.hh revision 2665
13560SN/A/* 23560SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 33560SN/A * All rights reserved. 43560SN/A * 53560SN/A * Redistribution and use in source and binary forms, with or without 63560SN/A * modification, are permitted provided that the following conditions are 73560SN/A * met: redistributions of source code must retain the above copyright 83560SN/A * notice, this list of conditions and the following disclaimer; 93560SN/A * redistributions in binary form must reproduce the above copyright 103560SN/A * notice, this list of conditions and the following disclaimer in the 113560SN/A * documentation and/or other materials provided with the distribution; 123560SN/A * neither the name of the copyright holders nor the names of its 133560SN/A * contributors may be used to endorse or promote products derived from 143560SN/A * this software without specific prior written permission. 153560SN/A * 163560SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173560SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183560SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193560SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203560SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213560SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223560SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233560SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243560SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253560SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263560SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273560SN/A * 283560SN/A * Authors: Kevin Lim 293560SN/A */ 303560SN/A 313560SN/A// @todo: Fix the instantaneous communication among all the stages within 3211793Sbrandon.potter@amd.com// iew. There's a clear delay between issue and execute, yet backwards 3311793Sbrandon.potter@amd.com// communication happens simultaneously. 343560SN/A// Update the statuses for each stage. 353560SN/A 363560SN/A#include <queue> 373560SN/A 3811793Sbrandon.potter@amd.com#include "base/timebuf.hh" 399329Sdam.sunwoo@arm.com#include "cpu/o3/iew.hh" 403560SN/A 413560SN/Atemplate<class Impl> 428232Snate@binkert.orgSimpleIEW<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, 433560SN/A SimpleIEW<Impl> *_iew) 443560SN/A : Event(&mainEventQueue, CPU_Tick_Pri), inst(_inst), iewStage(_iew) 453560SN/A{ 463560SN/A this->setFlags(Event::AutoDelete); 473560SN/A} 483560SN/A 493560SN/Atemplate<class Impl> 503560SN/Avoid 513560SN/ASimpleIEW<Impl>::WritebackEvent::process() 523560SN/A{ 533560SN/A DPRINTF(IEW, "IEW: WRITEBACK EVENT!!!!\n"); 543560SN/A 553560SN/A // Need to insert instruction into queue to commit 563560SN/A iewStage->instToCommit(inst); 573560SN/A // Need to execute second half of the instruction, do actual writing to 583560SN/A // registers and such 593560SN/A inst->execute(); 603560SN/A} 613560SN/A 623560SN/Atemplate<class Impl> 633560SN/Aconst char * 643560SN/ASimpleIEW<Impl>::WritebackEvent::description() 653560SN/A{ 663560SN/A return "LSQ writeback event"; 673560SN/A} 683560SN/A 693560SN/Atemplate<class Impl> 703560SN/ASimpleIEW<Impl>::SimpleIEW(Params ¶ms) 713560SN/A : // Just make this time buffer really big for now 723560SN/A issueToExecQueue(5, 5), 733560SN/A instQueue(params), 743560SN/A ldstQueue(params), 753560SN/A commitToIEWDelay(params.commitToIEWDelay), 763560SN/A renameToIEWDelay(params.renameToIEWDelay), 773560SN/A issueToExecuteDelay(params.issueToExecuteDelay), 783560SN/A issueReadWidth(params.issueWidth), 793560SN/A issueWidth(params.issueWidth), 803560SN/A executeWidth(params.executeWidth) 813560SN/A{ 823560SN/A DPRINTF(IEW, "IEW: executeIntWidth: %i.\n", params.executeIntWidth); 833560SN/A _status = Idle; 843560SN/A _issueStatus = Idle; 853560SN/A _exeStatus = Idle; 863560SN/A _wbStatus = Idle; 873560SN/A 883560SN/A // Setup wire to read instructions coming from issue. 893560SN/A fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay); 903560SN/A 913560SN/A // Instruction queue needs the queue between issue and execute. 923560SN/A instQueue.setIssueToExecuteQueue(&issueToExecQueue); 933560SN/A 943560SN/A ldstQueue.setIEW(this); 953560SN/A} 963560SN/A 973560SN/Atemplate <class Impl> 983560SN/Avoid 993560SN/ASimpleIEW<Impl>::regStats() 1003560SN/A{ 1013560SN/A instQueue.regStats(); 1023560SN/A 1033560SN/A iewIdleCycles 1043560SN/A .name(name() + ".iewIdleCycles") 1053560SN/A .desc("Number of cycles IEW is idle"); 1063560SN/A 1073560SN/A iewSquashCycles 1083560SN/A .name(name() + ".iewSquashCycles") 1093560SN/A .desc("Number of cycles IEW is squashing"); 1103560SN/A 1113560SN/A iewBlockCycles 1123560SN/A .name(name() + ".iewBlockCycles") 1133560SN/A .desc("Number of cycles IEW is blocking"); 1143560SN/A 1153560SN/A iewUnblockCycles 1163560SN/A .name(name() + ".iewUnblockCycles") 1173560SN/A .desc("Number of cycles IEW is unblocking"); 1183560SN/A 1193560SN/A// iewWBInsts; 1203560SN/A 1213560SN/A iewDispatchedInsts 1223560SN/A .name(name() + ".iewDispatchedInsts") 1233560SN/A .desc("Number of instructions dispatched to IQ"); 1243560SN/A 1253560SN/A iewDispSquashedInsts 1263560SN/A .name(name() + ".iewDispSquashedInsts") 1273560SN/A .desc("Number of squashed instructions skipped by dispatch"); 1283560SN/A 1293560SN/A iewDispLoadInsts 1303560SN/A .name(name() + ".iewDispLoadInsts") 1313560SN/A .desc("Number of dispatched load instructions"); 1323560SN/A 1333560SN/A iewDispStoreInsts 1343560SN/A .name(name() + ".iewDispStoreInsts") 1353560SN/A .desc("Number of dispatched store instructions"); 1363560SN/A 1373560SN/A iewDispNonSpecInsts 1383560SN/A .name(name() + ".iewDispNonSpecInsts") 1393560SN/A .desc("Number of dispatched non-speculative instructions"); 1403560SN/A 1413560SN/A iewIQFullEvents 1425191Ssaidi@eecs.umich.edu .name(name() + ".iewIQFullEvents") 1435191Ssaidi@eecs.umich.edu .desc("Number of times the IQ has become full, causing a stall"); 1445191Ssaidi@eecs.umich.edu 1453560SN/A iewExecutedInsts 1463560SN/A .name(name() + ".iewExecutedInsts") 1477823Ssteve.reinhardt@amd.com .desc("Number of executed instructions"); 1483560SN/A 1497823Ssteve.reinhardt@amd.com iewExecLoadInsts 1503560SN/A .name(name() + ".iewExecLoadInsts") 1513560SN/A .desc("Number of load instructions executed"); 1523560SN/A 1533560SN/A iewExecStoreInsts 1543560SN/A .name(name() + ".iewExecStoreInsts") 1553560SN/A .desc("Number of store instructions executed"); 1565568Snate@binkert.org 1573560SN/A iewExecSquashedInsts 1583560SN/A .name(name() + ".iewExecSquashedInsts") 1593560SN/A .desc("Number of squashed instructions skipped in execute"); 1603560SN/A 1613560SN/A memOrderViolationEvents 1623560SN/A .name(name() + ".memOrderViolationEvents") 1633560SN/A .desc("Number of memory order violations"); 1643560SN/A 1653560SN/A predictedTakenIncorrect 1663560SN/A .name(name() + ".predictedTakenIncorrect") 1673560SN/A .desc("Number of branches that were predicted taken incorrectly"); 1683560SN/A} 1693560SN/A 1703560SN/Atemplate<class Impl> 1715191Ssaidi@eecs.umich.eduvoid 1725191Ssaidi@eecs.umich.eduSimpleIEW<Impl>::setCPU(FullCPU *cpu_ptr) 1735191Ssaidi@eecs.umich.edu{ 1745191Ssaidi@eecs.umich.edu DPRINTF(IEW, "IEW: Setting CPU pointer.\n"); 1753560SN/A cpu = cpu_ptr; 1763560SN/A 1773560SN/A instQueue.setCPU(cpu_ptr); 1783560SN/A ldstQueue.setCPU(cpu_ptr); 1793560SN/A} 1803560SN/A 1813560SN/Atemplate<class Impl> 1823560SN/Avoid 1833560SN/ASimpleIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 1843560SN/A{ 1853560SN/A DPRINTF(IEW, "IEW: Setting time buffer pointer.\n"); 1863560SN/A timeBuffer = tb_ptr; 18710905Sandreas.sandberg@arm.com 1883560SN/A // Setup wire to read information from time buffer, from commit. 18910905Sandreas.sandberg@arm.com fromCommit = timeBuffer->getWire(-commitToIEWDelay); 1903560SN/A 1913560SN/A // Setup wire to write information back to previous stages. 1923560SN/A toRename = timeBuffer->getWire(0); 1933560SN/A 1943560SN/A // Instruction queue also needs main time buffer. 1953560SN/A instQueue.setTimeBuffer(tb_ptr); 1963560SN/A} 19710905Sandreas.sandberg@arm.com 1983560SN/Atemplate<class Impl> 19910905Sandreas.sandberg@arm.comvoid 2003560SN/ASimpleIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 2013560SN/A{ 2023560SN/A DPRINTF(IEW, "IEW: Setting rename queue pointer.\n"); 2033560SN/A renameQueue = rq_ptr; 2043560SN/A 2053560SN/A // Setup wire to read information from rename queue. 2063560SN/A fromRename = renameQueue->getWire(-renameToIEWDelay); 2075568Snate@binkert.org} 2085568Snate@binkert.org 209template<class Impl> 210void 211SimpleIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) 212{ 213 DPRINTF(IEW, "IEW: Setting IEW queue pointer.\n"); 214 iewQueue = iq_ptr; 215 216 // Setup wire to write instructions to commit. 217 toCommit = iewQueue->getWire(0); 218} 219 220template<class Impl> 221void 222SimpleIEW<Impl>::setRenameMap(RenameMap *rm_ptr) 223{ 224 DPRINTF(IEW, "IEW: Setting rename map pointer.\n"); 225 renameMap = rm_ptr; 226} 227 228template<class Impl> 229void 230SimpleIEW<Impl>::squash() 231{ 232 DPRINTF(IEW, "IEW: Squashing all instructions.\n"); 233 _status = Squashing; 234 235 // Tell the IQ to start squashing. 236 instQueue.squash(); 237 238 // Tell the LDSTQ to start squashing. 239 ldstQueue.squash(fromCommit->commitInfo.doneSeqNum); 240} 241 242template<class Impl> 243void 244SimpleIEW<Impl>::squashDueToBranch(DynInstPtr &inst) 245{ 246 DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n", 247 inst->PC); 248 // Perhaps leave the squashing up to the ROB stage to tell it when to 249 // squash? 250 _status = Squashing; 251 252 // Tell rename to squash through the time buffer. 253 toCommit->squash = true; 254 // Also send PC update information back to prior stages. 255 toCommit->squashedSeqNum = inst->seqNum; 256 toCommit->mispredPC = inst->readPC(); 257 toCommit->nextPC = inst->readNextPC(); 258 toCommit->branchMispredict = true; 259 // Prediction was incorrect, so send back inverse. 260 toCommit->branchTaken = inst->readNextPC() != 261 (inst->readPC() + sizeof(TheISA::MachInst)); 262} 263 264template<class Impl> 265void 266SimpleIEW<Impl>::squashDueToMem(DynInstPtr &inst) 267{ 268 DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n", 269 inst->PC); 270 // Perhaps leave the squashing up to the ROB stage to tell it when to 271 // squash? 272 _status = Squashing; 273 274 // Tell rename to squash through the time buffer. 275 toCommit->squash = true; 276 // Also send PC update information back to prior stages. 277 toCommit->squashedSeqNum = inst->seqNum; 278 toCommit->nextPC = inst->readNextPC(); 279} 280 281template<class Impl> 282void 283SimpleIEW<Impl>::block() 284{ 285 DPRINTF(IEW, "IEW: Blocking.\n"); 286 // Set the status to Blocked. 287 _status = Blocked; 288 289 // Add the current inputs to the skid buffer so they can be 290 // reprocessed when this stage unblocks. 291 skidBuffer.push(*fromRename); 292 293 // Note that this stage only signals previous stages to stall when 294 // it is the cause of the stall originates at this stage. Otherwise 295 // the previous stages are expected to check all possible stall signals. 296} 297 298template<class Impl> 299inline void 300SimpleIEW<Impl>::unblock() 301{ 302 // Check if there's information in the skid buffer. If there is, then 303 // set status to unblocking, otherwise set it directly to running. 304 DPRINTF(IEW, "IEW: Reading instructions out of the skid " 305 "buffer.\n"); 306 // Remove the now processed instructions from the skid buffer. 307 skidBuffer.pop(); 308 309 // If there's still information in the skid buffer, then 310 // continue to tell previous stages to stall. They will be 311 // able to restart once the skid buffer is empty. 312 if (!skidBuffer.empty()) { 313 toRename->iewInfo.stall = true; 314 } else { 315 DPRINTF(IEW, "IEW: Stage is done unblocking.\n"); 316 _status = Running; 317 } 318} 319 320template<class Impl> 321void 322SimpleIEW<Impl>::wakeDependents(DynInstPtr &inst) 323{ 324 instQueue.wakeDependents(inst); 325} 326 327 328template<class Impl> 329void 330SimpleIEW<Impl>::instToCommit(DynInstPtr &inst) 331{ 332 333} 334 335template <class Impl> 336void 337SimpleIEW<Impl>::dispatchInsts() 338{ 339 //////////////////////////////////////// 340 // DISPATCH/ISSUE stage 341 //////////////////////////////////////// 342 343 //Put into its own function? 344 //Add instructions to IQ if there are any instructions there 345 346 // Check if there are any instructions coming from rename, and we're. 347 // not squashing. 348 if (fromRename->size > 0) { 349 int insts_to_add = fromRename->size; 350 351 // Loop through the instructions, putting them in the instruction 352 // queue. 353 for (int inst_num = 0; inst_num < insts_to_add; ++inst_num) 354 { 355 DynInstPtr inst = fromRename->insts[inst_num]; 356 357 // Make sure there's a valid instruction there. 358 assert(inst); 359 360 DPRINTF(IEW, "IEW: Issue: Adding PC %#x to IQ.\n", 361 inst->readPC()); 362 363 // Be sure to mark these instructions as ready so that the 364 // commit stage can go ahead and execute them, and mark 365 // them as issued so the IQ doesn't reprocess them. 366 if (inst->isSquashed()) { 367 ++iewDispSquashedInsts; 368 continue; 369 } else if (instQueue.isFull()) { 370 DPRINTF(IEW, "IEW: Issue: IQ has become full.\n"); 371 // Call function to start blocking. 372 block(); 373 // Tell previous stage to stall. 374 toRename->iewInfo.stall = true; 375 376 ++iewIQFullEvents; 377 break; 378 } else if (inst->isLoad()) { 379 DPRINTF(IEW, "IEW: Issue: Memory instruction " 380 "encountered, adding to LDSTQ.\n"); 381 382 // Reserve a spot in the load store queue for this 383 // memory access. 384 ldstQueue.insertLoad(inst); 385 386 ++iewDispLoadInsts; 387 } else if (inst->isStore()) { 388 ldstQueue.insertStore(inst); 389 390 ++iewDispStoreInsts; 391 } else if (inst->isNonSpeculative()) { 392 DPRINTF(IEW, "IEW: Issue: Nonspeculative instruction " 393 "encountered, skipping.\n"); 394 395 // Same hack as with stores. 396 inst->setCanCommit(); 397 398 // Specificall insert it as nonspeculative. 399 instQueue.insertNonSpec(inst); 400 401 ++iewDispNonSpecInsts; 402 403 continue; 404 } else if (inst->isNop()) { 405 DPRINTF(IEW, "IEW: Issue: Nop instruction encountered " 406 ", skipping.\n"); 407 408 inst->setIssued(); 409 inst->setExecuted(); 410 inst->setCanCommit(); 411 412 instQueue.advanceTail(inst); 413 414 continue; 415 } else if (inst->isExecuted()) { 416 assert(0 && "Instruction shouldn't be executed.\n"); 417 DPRINTF(IEW, "IEW: Issue: Executed branch encountered, " 418 "skipping.\n"); 419 420 inst->setIssued(); 421 inst->setCanCommit(); 422 423 instQueue.advanceTail(inst); 424 425 continue; 426 } 427 428 // If the instruction queue is not full, then add the 429 // instruction. 430 instQueue.insert(fromRename->insts[inst_num]); 431 432 ++iewDispatchedInsts; 433 } 434 } 435} 436 437template <class Impl> 438void 439SimpleIEW<Impl>::executeInsts() 440{ 441 //////////////////////////////////////// 442 //EXECUTE/WRITEBACK stage 443 //////////////////////////////////////// 444 445 //Put into its own function? 446 //Similarly should probably have separate execution for int vs FP. 447 // Above comment is handled by the issue queue only issuing a valid 448 // mix of int/fp instructions. 449 //Actually okay to just have one execution, buuuuuut will need 450 //somewhere that defines the execution latency of all instructions. 451 // @todo: Move to the FU pool used in the current full cpu. 452 453 int fu_usage = 0; 454 bool fetch_redirect = false; 455 int inst_slot = 0; 456 int time_slot = 0; 457 458 // Execute/writeback any instructions that are available. 459 for (int inst_num = 0; 460 fu_usage < executeWidth && /* Haven't exceeded available FU's. */ 461 inst_num < issueWidth && 462 fromIssue->insts[inst_num]; 463 ++inst_num) { 464 465 DPRINTF(IEW, "IEW: Execute: Executing instructions from IQ.\n"); 466 467 // Get instruction from issue's queue. 468 DynInstPtr inst = fromIssue->insts[inst_num]; 469 470 DPRINTF(IEW, "IEW: Execute: Processing PC %#x.\n", inst->readPC()); 471 472 // Check if the instruction is squashed; if so then skip it 473 // and don't count it towards the FU usage. 474 if (inst->isSquashed()) { 475 DPRINTF(IEW, "IEW: Execute: Instruction was squashed.\n"); 476 477 // Consider this instruction executed so that commit can go 478 // ahead and retire the instruction. 479 inst->setExecuted(); 480 481 toCommit->insts[inst_num] = inst; 482 483 ++iewExecSquashedInsts; 484 485 continue; 486 } 487 488 inst->setExecuted(); 489 490 // If an instruction is executed, then count it towards FU usage. 491 ++fu_usage; 492 493 // Execute instruction. 494 // Note that if the instruction faults, it will be handled 495 // at the commit stage. 496 if (inst->isMemRef()) { 497 DPRINTF(IEW, "IEW: Execute: Calculating address for memory " 498 "reference.\n"); 499 500 // Tell the LDSTQ to execute this instruction (if it is a load). 501 if (inst->isLoad()) { 502 ldstQueue.executeLoad(inst); 503 504 ++iewExecLoadInsts; 505 } else if (inst->isStore()) { 506 ldstQueue.executeStore(inst); 507 508 ++iewExecStoreInsts; 509 } else { 510 panic("IEW: Unexpected memory type!\n"); 511 } 512 513 } else { 514 inst->execute(); 515 516 ++iewExecutedInsts; 517 } 518 519 // First check the time slot that this instruction will write 520 // to. If there are free write ports at the time, then go ahead 521 // and write the instruction to that time. If there are not, 522 // keep looking back to see where's the first time there's a 523 // free slot. What happens if you run out of free spaces? 524 // For now naively assume that all instructions take one cycle. 525 // Otherwise would have to look into the time buffer based on the 526 // latency of the instruction. 527 (*iewQueue)[time_slot].insts[inst_slot]; 528 while ((*iewQueue)[time_slot].insts[inst_slot]) { 529 if (inst_slot < issueWidth) { 530 ++inst_slot; 531 } else { 532 ++time_slot; 533 inst_slot = 0; 534 } 535 536 assert(time_slot < 5); 537 } 538 539 // May actually have to work this out, especially with loads and stores 540 541 // Add finished instruction to queue to commit. 542 (*iewQueue)[time_slot].insts[inst_slot] = inst; 543 (*iewQueue)[time_slot].size++; 544 545 // Check if branch was correct. This check happens after the 546 // instruction is added to the queue because even if the branch 547 // is mispredicted, the branch instruction itself is still valid. 548 // Only handle this if there hasn't already been something that 549 // redirects fetch in this group of instructions. 550 if (!fetch_redirect) { 551 if (inst->mispredicted()) { 552 fetch_redirect = true; 553 554 DPRINTF(IEW, "IEW: Execute: Branch mispredict detected.\n"); 555 DPRINTF(IEW, "IEW: Execute: Redirecting fetch to PC: %#x.\n", 556 inst->nextPC); 557 558 // If incorrect, then signal the ROB that it must be squashed. 559 squashDueToBranch(inst); 560 561 if (inst->predTaken()) { 562 predictedTakenIncorrect++; 563 } 564 } else if (ldstQueue.violation()) { 565 fetch_redirect = true; 566 567 // Get the DynInst that caused the violation. 568 DynInstPtr violator = ldstQueue.getMemDepViolator(); 569 570 DPRINTF(IEW, "IEW: LDSTQ detected a violation. Violator PC: " 571 "%#x, inst PC: %#x. Addr is: %#x.\n", 572 violator->readPC(), inst->readPC(), inst->physEffAddr); 573 574 // Tell the instruction queue that a violation has occured. 575 instQueue.violation(inst, violator); 576 577 // Squash. 578 squashDueToMem(inst); 579 580 ++memOrderViolationEvents; 581 } 582 } 583 } 584} 585 586template<class Impl> 587void 588SimpleIEW<Impl>::tick() 589{ 590 // Considering putting all the state-determining stuff in this section. 591 592 // Try to fill up issue queue with as many instructions as bandwidth 593 // allows. 594 // Decode should try to execute as many instructions as its bandwidth 595 // will allow, as long as it is not currently blocked. 596 597 // Check if the stage is in a running status. 598 if (_status != Blocked && _status != Squashing) { 599 DPRINTF(IEW, "IEW: Status is not blocked, attempting to run " 600 "stage.\n"); 601 iew(); 602 603 // If it's currently unblocking, check to see if it should switch 604 // to running. 605 if (_status == Unblocking) { 606 unblock(); 607 608 ++iewUnblockCycles; 609 } 610 } else if (_status == Squashing) { 611 612 DPRINTF(IEW, "IEW: Still squashing.\n"); 613 614 // Check if stage should remain squashing. Stop squashing if the 615 // squash signal clears. 616 if (!fromCommit->commitInfo.squash && 617 !fromCommit->commitInfo.robSquashing) { 618 DPRINTF(IEW, "IEW: Done squashing, changing status to " 619 "running.\n"); 620 621 _status = Running; 622 instQueue.stopSquash(); 623 } else { 624 instQueue.doSquash(); 625 } 626 627 ++iewSquashCycles; 628 } else if (_status == Blocked) { 629 // Continue to tell previous stage to stall. 630 toRename->iewInfo.stall = true; 631 632 // Check if possible stall conditions have cleared. 633 if (!fromCommit->commitInfo.stall && 634 !instQueue.isFull()) { 635 DPRINTF(IEW, "IEW: Stall signals cleared, going to unblock.\n"); 636 _status = Unblocking; 637 } 638 639 // If there's still instructions coming from rename, continue to 640 // put them on the skid buffer. 641 if (fromRename->size == 0) { 642 block(); 643 } 644 645 if (fromCommit->commitInfo.squash || 646 fromCommit->commitInfo.robSquashing) { 647 squash(); 648 } 649 650 ++iewBlockCycles; 651 } 652 653 // @todo: Maybe put these at the beginning, so if it's idle it can 654 // return early. 655 // Write back number of free IQ entries here. 656 toRename->iewInfo.freeIQEntries = instQueue.numFreeEntries(); 657 658 ldstQueue.writebackStores(); 659 660 // Check the committed load/store signals to see if there's a load 661 // or store to commit. Also check if it's being told to execute a 662 // nonspeculative instruction. 663 // This is pretty inefficient... 664 if (!fromCommit->commitInfo.squash && 665 !fromCommit->commitInfo.robSquashing) { 666 ldstQueue.commitStores(fromCommit->commitInfo.doneSeqNum); 667 ldstQueue.commitLoads(fromCommit->commitInfo.doneSeqNum); 668 } 669 670 if (fromCommit->commitInfo.nonSpecSeqNum != 0) { 671 instQueue.scheduleNonSpec(fromCommit->commitInfo.nonSpecSeqNum); 672 } 673 674 DPRINTF(IEW, "IEW: IQ has %i free entries.\n", 675 instQueue.numFreeEntries()); 676} 677 678template<class Impl> 679void 680SimpleIEW<Impl>::iew() 681{ 682 // Might want to put all state checks in the tick() function. 683 // Check if being told to stall from commit. 684 if (fromCommit->commitInfo.stall) { 685 block(); 686 return; 687 } else if (fromCommit->commitInfo.squash || 688 fromCommit->commitInfo.robSquashing) { 689 // Also check if commit is telling this stage to squash. 690 squash(); 691 return; 692 } 693 694 dispatchInsts(); 695 696 // Have the instruction queue try to schedule any ready instructions. 697 instQueue.scheduleReadyInsts(); 698 699 executeInsts(); 700 701 // Loop through the head of the time buffer and wake any dependents. 702 // These instructions are about to write back. In the simple model 703 // this loop can really happen within the previous loop, but when 704 // instructions have actual latencies, this loop must be separate. 705 // Also mark scoreboard that this instruction is finally complete. 706 // Either have IEW have direct access to rename map, or have this as 707 // part of backwards communication. 708 for (int inst_num = 0; inst_num < issueWidth && 709 toCommit->insts[inst_num]; inst_num++) 710 { 711 DynInstPtr inst = toCommit->insts[inst_num]; 712 713 DPRINTF(IEW, "IEW: Sending instructions to commit, PC %#x.\n", 714 inst->readPC()); 715 716 if(!inst->isSquashed()) { 717 instQueue.wakeDependents(inst); 718 719 for (int i = 0; i < inst->numDestRegs(); i++) 720 { 721 renameMap->markAsReady(inst->renamedDestRegIdx(i)); 722 } 723 } 724 } 725 726 // Also should advance its own time buffers if the stage ran. 727 // Not the best place for it, but this works (hopefully). 728 issueToExecQueue.advance(); 729} 730 731#if !FULL_SYSTEM 732template<class Impl> 733void 734SimpleIEW<Impl>::lsqWriteback() 735{ 736 ldstQueue.writebackAllInsts(); 737} 738#endif 739