gem5  v21.0.1.0
inst_queue_impl.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2014, 2017-2020 ARM Limited
3  * Copyright (c) 2013 Advanced Micro Devices, Inc.
4  * All rights reserved.
5  *
6  * The license below extends only to copyright in the software and shall
7  * not be construed as granting a license to any other intellectual
8  * property including but not limited to intellectual property relating
9  * to a hardware implementation of the functionality of the software
10  * licensed hereunder. You may use the software subject to the license
11  * terms below provided that you ensure that this notice is replicated
12  * unmodified and in its entirety in all distributions of the software,
13  * modified or unmodified, in source code or in binary form.
14  *
15  * Copyright (c) 2004-2006 The Regents of The University of Michigan
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 #ifndef __CPU_O3_INST_QUEUE_IMPL_HH__
43 #define __CPU_O3_INST_QUEUE_IMPL_HH__
44 
45 #include <limits>
46 #include <vector>
47 
48 #include "base/logging.hh"
49 #include "cpu/o3/fu_pool.hh"
50 #include "cpu/o3/inst_queue.hh"
51 #include "debug/IQ.hh"
52 #include "enums/OpClass.hh"
53 #include "params/DerivO3CPU.hh"
54 #include "sim/core.hh"
55 
56 // clang complains about std::set being overloaded with Packet::set if
57 // we open up the entire namespace std
58 using std::list;
59 
60 template <class Impl>
62  int fu_idx, InstructionQueue<Impl> *iq_ptr)
63  : Event(Stat_Event_Pri, AutoDelete),
64  inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
65 {
66 }
67 
68 template <class Impl>
69 void
71 {
72  iqPtr->processFUCompletion(inst, freeFU ? fuIdx : -1);
73  inst = NULL;
74 }
75 
76 
77 template <class Impl>
78 const char *
80 {
81  return "Functional unit completion";
82 }
83 
84 template <class Impl>
86  const DerivO3CPUParams &params)
87  : cpu(cpu_ptr),
88  iewStage(iew_ptr),
89  fuPool(params.fuPool),
90  iqPolicy(params.smtIQPolicy),
91  numThreads(params.numThreads),
92  numEntries(params.numIQEntries),
93  totalWidth(params.issueWidth),
96  iqIOStats(cpu)
97 {
98  assert(fuPool);
99 
100  // Set the number of total physical registers
101  // As the vector registers have two addressing modes, they are added twice
102  numPhysRegs = params.numPhysIntRegs + params.numPhysFloatRegs +
103  params.numPhysVecRegs +
104  params.numPhysVecRegs * TheISA::NumVecElemPerVecReg +
105  params.numPhysVecPredRegs +
106  params.numPhysCCRegs;
107 
108  //Create an entry for each physical register within the
109  //dependency graph.
110  dependGraph.resize(numPhysRegs);
111 
112  // Resize the register scoreboard.
113  regScoreboard.resize(numPhysRegs);
114 
115  //Initialize Mem Dependence Units
116  for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
117  memDepUnit[tid].init(params, tid, cpu_ptr);
118  memDepUnit[tid].setIQ(this);
119  }
120 
121  resetState();
122 
123  //Figure out resource sharing policy
124  if (iqPolicy == SMTQueuePolicy::Dynamic) {
125  //Set Max Entries to Total ROB Capacity
126  for (ThreadID tid = 0; tid < numThreads; tid++) {
127  maxEntries[tid] = numEntries;
128  }
129 
130  } else if (iqPolicy == SMTQueuePolicy::Partitioned) {
131  //@todo:make work if part_amt doesnt divide evenly.
132  int part_amt = numEntries / numThreads;
133 
134  //Divide ROB up evenly
135  for (ThreadID tid = 0; tid < numThreads; tid++) {
136  maxEntries[tid] = part_amt;
137  }
138 
139  DPRINTF(IQ, "IQ sharing policy set to Partitioned:"
140  "%i entries per thread.\n",part_amt);
141  } else if (iqPolicy == SMTQueuePolicy::Threshold) {
142  double threshold = (double)params.smtIQThreshold / 100;
143 
144  int thresholdIQ = (int)((double)threshold * numEntries);
145 
146  //Divide up by threshold amount
147  for (ThreadID tid = 0; tid < numThreads; tid++) {
148  maxEntries[tid] = thresholdIQ;
149  }
150 
151  DPRINTF(IQ, "IQ sharing policy set to Threshold:"
152  "%i entries per thread.\n",thresholdIQ);
153  }
154  for (ThreadID tid = numThreads; tid < Impl::MaxThreads; tid++) {
155  maxEntries[tid] = 0;
156  }
157 }
158 
159 template <class Impl>
161 {
162  dependGraph.reset();
163 #ifdef DEBUG
164  cprintf("Nodes traversed: %i, removed: %i\n",
165  dependGraph.nodesTraversed, dependGraph.nodesRemoved);
166 #endif
167 }
168 
169 template <class Impl>
170 std::string
172 {
173  return cpu->name() + ".iq";
174 }
175 
176 template <class Impl>
178 IQStats::IQStats(O3CPU *cpu, const unsigned &total_width)
179  : Stats::Group(cpu),
180  ADD_STAT(instsAdded, UNIT_COUNT,
181  "Number of instructions added to the IQ (excludes non-spec)"),
182  ADD_STAT(nonSpecInstsAdded, UNIT_COUNT,
183  "Number of non-speculative instructions added to the IQ"),
184  ADD_STAT(instsIssued, UNIT_COUNT, "Number of instructions issued"),
185  ADD_STAT(intInstsIssued, UNIT_COUNT,
186  "Number of integer instructions issued"),
187  ADD_STAT(floatInstsIssued, UNIT_COUNT,
188  "Number of float instructions issued"),
189  ADD_STAT(branchInstsIssued, UNIT_COUNT,
190  "Number of branch instructions issued"),
191  ADD_STAT(memInstsIssued, UNIT_COUNT,
192  "Number of memory instructions issued"),
193  ADD_STAT(miscInstsIssued, UNIT_COUNT,
194  "Number of miscellaneous instructions issued"),
195  ADD_STAT(squashedInstsIssued, UNIT_COUNT,
196  "Number of squashed instructions issued"),
197  ADD_STAT(squashedInstsExamined, UNIT_COUNT,
198  "Number of squashed instructions iterated over during squash; "
199  "mainly for profiling"),
200  ADD_STAT(squashedOperandsExamined, UNIT_COUNT,
201  "Number of squashed operands that are examined and possibly "
202  "removed from graph"),
203  ADD_STAT(squashedNonSpecRemoved, UNIT_COUNT,
204  "Number of squashed non-spec instructions that were removed"),
205  ADD_STAT(numIssuedDist, UNIT_COUNT, "Number of insts issued each cycle"),
206  ADD_STAT(statFuBusy, UNIT_COUNT,
207  "attempts to use FU when none available"),
208  ADD_STAT(statIssuedInstType, UNIT_COUNT,
209  "Number of instructions issued per FU type, per thread"),
210  ADD_STAT(issueRate, UNIT_RATE(Stats::Units::Count, Stats::Units::Cycle),
211  "Inst issue rate", instsIssued / cpu->baseStats.numCycles),
212  ADD_STAT(fuBusy, UNIT_COUNT, "FU busy when requested"),
213  ADD_STAT(fuBusyRate, UNIT_RATE(Stats::Units::Count, Stats::Units::Count),
214  "FU busy rate (busy events/executed inst)")
215 {
216  instsAdded
217  .prereq(instsAdded);
218 
221 
224 
227 
230 
233 
236 
239 
242 
245 
248 
251 /*
252  queueResDist
253  .init(Num_OpClasses, 0, 99, 2)
254  .name(name() + ".IQ:residence:")
255  .desc("cycles from dispatch to issue")
256  .flags(total | pdf | cdf )
257  ;
258  for (int i = 0; i < Num_OpClasses; ++i) {
259  queueResDist.subname(i, opClassStrings[i]);
260  }
261 */
263  .init(0,total_width,1)
264  .flags(Stats::pdf)
265  ;
266 /*
267  dist_unissued
268  .init(Num_OpClasses+2)
269  .name(name() + ".unissued_cause")
270  .desc("Reason ready instruction not issued")
271  .flags(pdf | dist)
272  ;
273  for (int i=0; i < (Num_OpClasses + 2); ++i) {
274  dist_unissued.subname(i, unissued_names[i]);
275  }
276 */
278  .init(cpu->numThreads,Enums::Num_OpClass)
280  ;
281  statIssuedInstType.ysubnames(Enums::OpClassStrings);
282 
283  //
284  // How long did instructions for a particular FU type wait prior to issue
285  //
286 /*
287  issueDelayDist
288  .init(Num_OpClasses,0,99,2)
289  .name(name() + ".")
290  .desc("cycles from operands ready to issue")
291  .flags(pdf | cdf)
292  ;
293  for (int i=0; i<Num_OpClasses; ++i) {
294  std::stringstream subname;
295  subname << opClassStrings[i] << "_delay";
296  issueDelayDist.subname(i, subname.str());
297  }
298 */
299  issueRate
301  ;
302 
303  statFuBusy
306  ;
307  for (int i=0; i < Num_OpClasses; ++i) {
308  statFuBusy.subname(i, Enums::OpClassStrings[i]);
309  }
310 
311  fuBusy
312  .init(cpu->numThreads)
314  ;
315 
316  fuBusyRate
318  ;
320 }
321 
322 template <class Impl>
325  : Stats::Group(parent),
326  ADD_STAT(intInstQueueReads, UNIT_COUNT,
327  "Number of integer instruction queue reads"),
328  ADD_STAT(intInstQueueWrites, UNIT_COUNT,
329  "Number of integer instruction queue writes"),
330  ADD_STAT(intInstQueueWakeupAccesses, UNIT_COUNT,
331  "Number of integer instruction queue wakeup accesses"),
332  ADD_STAT(fpInstQueueReads, UNIT_COUNT,
333  "Number of floating instruction queue reads"),
334  ADD_STAT(fpInstQueueWrites, UNIT_COUNT,
335  "Number of floating instruction queue writes"),
336  ADD_STAT(fpInstQueueWakeupAccesses, UNIT_COUNT,
337  "Number of floating instruction queue wakeup accesses"),
338  ADD_STAT(vecInstQueueReads, UNIT_COUNT,
339  "Number of vector instruction queue reads"),
340  ADD_STAT(vecInstQueueWrites, UNIT_COUNT,
341  "Number of vector instruction queue writes"),
342  ADD_STAT(vecInstQueueWakeupAccesses, UNIT_COUNT,
343  "Number of vector instruction queue wakeup accesses"),
344  ADD_STAT(intAluAccesses, UNIT_COUNT, "Number of integer alu accesses"),
345  ADD_STAT(fpAluAccesses, UNIT_COUNT,
346  "Number of floating point alu accesses"),
347  ADD_STAT(vecAluAccesses, UNIT_COUNT, "Number of vector alu accesses")
348 {
349  using namespace Stats;
351  .flags(total);
352 
354  .flags(total);
355 
357  .flags(total);
358 
360  .flags(total);
361 
363  .flags(total);
364 
366  .flags(total);
367 
369  .flags(total);
370 
372  .flags(total);
373 
375  .flags(total);
376 
378  .flags(total);
379 
381  .flags(total);
382 
384  .flags(total);
385 }
386 
387 template <class Impl>
388 void
390 {
391  //Initialize thread IQ counts
392  for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
393  count[tid] = 0;
394  instList[tid].clear();
395  }
396 
397  // Initialize the number of free IQ entries.
399 
400  // Note that in actuality, the registers corresponding to the logical
401  // registers start off as ready. However this doesn't matter for the
402  // IQ as the instruction should have been correctly told if those
403  // registers are ready in rename. Thus it can all be initialized as
404  // unready.
405  for (int i = 0; i < numPhysRegs; ++i) {
406  regScoreboard[i] = false;
407  }
408 
409  for (ThreadID tid = 0; tid < Impl::MaxThreads; ++tid) {
410  squashedSeqNum[tid] = 0;
411  }
412 
413  for (int i = 0; i < Num_OpClasses; ++i) {
414  while (!readyInsts[i].empty())
415  readyInsts[i].pop();
416  queueOnList[i] = false;
417  readyIt[i] = listOrder.end();
418  }
419  nonSpecInsts.clear();
420  listOrder.clear();
421  deferredMemInsts.clear();
422  blockedMemInsts.clear();
423  retryMemInsts.clear();
424  wbOutstanding = 0;
425 }
426 
427 template <class Impl>
428 void
430 {
431  activeThreads = at_ptr;
432 }
433 
434 template <class Impl>
435 void
437 {
438  issueToExecuteQueue = i2e_ptr;
439 }
440 
441 template <class Impl>
442 void
444 {
445  timeBuffer = tb_ptr;
446 
448 }
449 
450 template <class Impl>
451 bool
453 {
454  bool drained = dependGraph.empty() &&
455  instsToExecute.empty() &&
456  wbOutstanding == 0;
457  for (ThreadID tid = 0; tid < numThreads; ++tid)
458  drained = drained && memDepUnit[tid].isDrained();
459 
460  return drained;
461 }
462 
463 template <class Impl>
464 void
466 {
467  assert(dependGraph.empty());
468  assert(instsToExecute.empty());
469  for (ThreadID tid = 0; tid < numThreads; ++tid)
471 }
472 
473 template <class Impl>
474 void
476 {
477  resetState();
478 }
479 
480 template <class Impl>
481 int
483 {
484  if (iqPolicy == SMTQueuePolicy::Partitioned) {
485  return numEntries / num_threads;
486  } else {
487  return 0;
488  }
489 }
490 
491 
492 template <class Impl>
493 void
495 {
496  if (iqPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) {
497  int active_threads = activeThreads->size();
498 
499  list<ThreadID>::iterator threads = activeThreads->begin();
501 
502  while (threads != end) {
503  ThreadID tid = *threads++;
504 
505  if (iqPolicy == SMTQueuePolicy::Partitioned) {
506  maxEntries[tid] = numEntries / active_threads;
507  } else if (iqPolicy == SMTQueuePolicy::Threshold &&
508  active_threads == 1) {
509  maxEntries[tid] = numEntries;
510  }
511  }
512  }
513 }
514 
515 template <class Impl>
516 unsigned
518 {
519  return freeEntries;
520 }
521 
522 template <class Impl>
523 unsigned
525 {
526  return maxEntries[tid] - count[tid];
527 }
528 
529 // Might want to do something more complex if it knows how many instructions
530 // will be issued this cycle.
531 template <class Impl>
532 bool
534 {
535  if (freeEntries == 0) {
536  return(true);
537  } else {
538  return(false);
539  }
540 }
541 
542 template <class Impl>
543 bool
545 {
546  if (numFreeEntries(tid) == 0) {
547  return(true);
548  } else {
549  return(false);
550  }
551 }
552 
553 template <class Impl>
554 bool
556 {
557  if (!listOrder.empty()) {
558  return true;
559  }
560 
561  for (int i = 0; i < Num_OpClasses; ++i) {
562  if (!readyInsts[i].empty()) {
563  return true;
564  }
565  }
566 
567  return false;
568 }
569 
570 template <class Impl>
571 void
573 {
574  if (new_inst->isFloating()) {
576  } else if (new_inst->isVector()) {
578  } else {
580  }
581  // Make sure the instruction is valid
582  assert(new_inst);
583 
584  DPRINTF(IQ, "Adding instruction [sn:%llu] PC %s to the IQ.\n",
585  new_inst->seqNum, new_inst->pcState());
586 
587  assert(freeEntries != 0);
588 
589  instList[new_inst->threadNumber].push_back(new_inst);
590 
591  --freeEntries;
592 
593  new_inst->setInIQ();
594 
595  // Look through its source registers (physical regs), and mark any
596  // dependencies.
597  addToDependents(new_inst);
598 
599  // Have this instruction set itself as the producer of its destination
600  // register(s).
601  addToProducers(new_inst);
602 
603  if (new_inst->isMemRef()) {
604  memDepUnit[new_inst->threadNumber].insert(new_inst);
605  } else {
606  addIfReady(new_inst);
607  }
608 
610 
611  count[new_inst->threadNumber]++;
612 
613  assert(freeEntries == (numEntries - countInsts()));
614 }
615 
616 template <class Impl>
617 void
619 {
620  // @todo: Clean up this code; can do it by setting inst as unable
621  // to issue, then calling normal insert on the inst.
622  if (new_inst->isFloating()) {
624  } else if (new_inst->isVector()) {
626  } else {
628  }
629 
630  assert(new_inst);
631 
632  nonSpecInsts[new_inst->seqNum] = new_inst;
633 
634  DPRINTF(IQ, "Adding non-speculative instruction [sn:%llu] PC %s "
635  "to the IQ.\n",
636  new_inst->seqNum, new_inst->pcState());
637 
638  assert(freeEntries != 0);
639 
640  instList[new_inst->threadNumber].push_back(new_inst);
641 
642  --freeEntries;
643 
644  new_inst->setInIQ();
645 
646  // Have this instruction set itself as the producer of its destination
647  // register(s).
648  addToProducers(new_inst);
649 
650  // If it's a memory instruction, add it to the memory dependency
651  // unit.
652  if (new_inst->isMemRef()) {
653  memDepUnit[new_inst->threadNumber].insertNonSpec(new_inst);
654  }
655 
657 
658  count[new_inst->threadNumber]++;
659 
660  assert(freeEntries == (numEntries - countInsts()));
661 }
662 
663 template <class Impl>
664 void
666 {
667  memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst);
668 
669  insertNonSpec(barr_inst);
670 }
671 
672 template <class Impl>
673 typename Impl::DynInstPtr
675 {
676  assert(!instsToExecute.empty());
677  DynInstPtr inst = std::move(instsToExecute.front());
678  instsToExecute.pop_front();
679  if (inst->isFloating()) {
681  } else if (inst->isVector()) {
683  } else {
685  }
686  return inst;
687 }
688 
689 template <class Impl>
690 void
692 {
693  assert(!readyInsts[op_class].empty());
694 
695  ListOrderEntry queue_entry;
696 
697  queue_entry.queueType = op_class;
698 
699  queue_entry.oldestInst = readyInsts[op_class].top()->seqNum;
700 
701  ListOrderIt list_it = listOrder.begin();
702  ListOrderIt list_end_it = listOrder.end();
703 
704  while (list_it != list_end_it) {
705  if ((*list_it).oldestInst > queue_entry.oldestInst) {
706  break;
707  }
708 
709  list_it++;
710  }
711 
712  readyIt[op_class] = listOrder.insert(list_it, queue_entry);
713  queueOnList[op_class] = true;
714 }
715 
716 template <class Impl>
717 void
719 {
720  // Get iterator of next item on the list
721  // Delete the original iterator
722  // Determine if the next item is either the end of the list or younger
723  // than the new instruction. If so, then add in a new iterator right here.
724  // If not, then move along.
725  ListOrderEntry queue_entry;
726  OpClass op_class = (*list_order_it).queueType;
727  ListOrderIt next_it = list_order_it;
728 
729  ++next_it;
730 
731  queue_entry.queueType = op_class;
732  queue_entry.oldestInst = readyInsts[op_class].top()->seqNum;
733 
734  while (next_it != listOrder.end() &&
735  (*next_it).oldestInst < queue_entry.oldestInst) {
736  ++next_it;
737  }
738 
739  readyIt[op_class] = listOrder.insert(next_it, queue_entry);
740 }
741 
742 template <class Impl>
743 void
745 {
746  DPRINTF(IQ, "Processing FU completion [sn:%llu]\n", inst->seqNum);
747  assert(!cpu->switchedOut());
748  // The CPU could have been sleeping until this op completed (*extremely*
749  // long latency op). Wake it if it was. This may be overkill.
750  --wbOutstanding;
751  iewStage->wakeCPU();
752 
753  if (fu_idx > -1)
754  fuPool->freeUnitNextCycle(fu_idx);
755 
756  // @todo: Ensure that these FU Completions happen at the beginning
757  // of a cycle, otherwise they could add too many instructions to
758  // the queue.
760  instsToExecute.push_back(inst);
761 }
762 
763 // @todo: Figure out a better way to remove the squashed items from the
764 // lists. Checking the top item of each list to see if it's squashed
765 // wastes time and forces jumps.
766 template <class Impl>
767 void
769 {
770  DPRINTF(IQ, "Attempting to schedule ready instructions from "
771  "the IQ.\n");
772 
773  IssueStruct *i2e_info = issueToExecuteQueue->access(0);
774 
775  DynInstPtr mem_inst;
776  while ((mem_inst = std::move(getDeferredMemInstToExecute()))) {
777  addReadyMemInst(mem_inst);
778  }
779 
780  // See if any cache blocked instructions are able to be executed
781  while ((mem_inst = std::move(getBlockedMemInstToExecute()))) {
782  addReadyMemInst(mem_inst);
783  }
784 
785  // Have iterator to head of the list
786  // While I haven't exceeded bandwidth or reached the end of the list,
787  // Try to get a FU that can do what this op needs.
788  // If successful, change the oldestInst to the new top of the list, put
789  // the queue in the proper place in the list.
790  // Increment the iterator.
791  // This will avoid trying to schedule a certain op class if there are no
792  // FUs that handle it.
793  int total_issued = 0;
794  ListOrderIt order_it = listOrder.begin();
795  ListOrderIt order_end_it = listOrder.end();
796 
797  while (total_issued < totalWidth && order_it != order_end_it) {
798  OpClass op_class = (*order_it).queueType;
799 
800  assert(!readyInsts[op_class].empty());
801 
802  DynInstPtr issuing_inst = readyInsts[op_class].top();
803 
804  if (issuing_inst->isFloating()) {
806  } else if (issuing_inst->isVector()) {
808  } else {
810  }
811 
812  assert(issuing_inst->seqNum == (*order_it).oldestInst);
813 
814  if (issuing_inst->isSquashed()) {
815  readyInsts[op_class].pop();
816 
817  if (!readyInsts[op_class].empty()) {
818  moveToYoungerInst(order_it);
819  } else {
820  readyIt[op_class] = listOrder.end();
821  queueOnList[op_class] = false;
822  }
823 
824  listOrder.erase(order_it++);
825 
827 
828  continue;
829  }
830 
831  int idx = FUPool::NoCapableFU;
832  Cycles op_latency = Cycles(1);
833  ThreadID tid = issuing_inst->threadNumber;
834 
835  if (op_class != No_OpClass) {
836  idx = fuPool->getUnit(op_class);
837  if (issuing_inst->isFloating()) {
839  } else if (issuing_inst->isVector()) {
841  } else {
843  }
844  if (idx > FUPool::NoFreeFU) {
845  op_latency = fuPool->getOpLatency(op_class);
846  }
847  }
848 
849  // If we have an instruction that doesn't require a FU, or a
850  // valid FU, then schedule for execution.
851  if (idx != FUPool::NoFreeFU) {
852  if (op_latency == Cycles(1)) {
853  i2e_info->size++;
854  instsToExecute.push_back(issuing_inst);
855 
856  // Add the FU onto the list of FU's to be freed next
857  // cycle if we used one.
858  if (idx >= 0)
860  } else {
861  bool pipelined = fuPool->isPipelined(op_class);
862  // Generate completion event for the FU
863  ++wbOutstanding;
864  FUCompletion *execution = new FUCompletion(issuing_inst,
865  idx, this);
866 
867  cpu->schedule(execution,
868  cpu->clockEdge(Cycles(op_latency - 1)));
869 
870  if (!pipelined) {
871  // If FU isn't pipelined, then it must be freed
872  // upon the execution completing.
873  execution->setFreeFU();
874  } else {
875  // Add the FU onto the list of FU's to be freed next cycle.
877  }
878  }
879 
880  DPRINTF(IQ, "Thread %i: Issuing instruction PC %s "
881  "[sn:%llu]\n",
882  tid, issuing_inst->pcState(),
883  issuing_inst->seqNum);
884 
885  readyInsts[op_class].pop();
886 
887  if (!readyInsts[op_class].empty()) {
888  moveToYoungerInst(order_it);
889  } else {
890  readyIt[op_class] = listOrder.end();
891  queueOnList[op_class] = false;
892  }
893 
894  issuing_inst->setIssued();
895  ++total_issued;
896 
897 #if TRACING_ON
898  issuing_inst->issueTick = curTick() - issuing_inst->fetchTick;
899 #endif
900 
901  if (!issuing_inst->isMemRef()) {
902  // Memory instructions can not be freed from the IQ until they
903  // complete.
904  ++freeEntries;
905  count[tid]--;
906  issuing_inst->clearInIQ();
907  } else {
908  memDepUnit[tid].issue(issuing_inst);
909  }
910 
911  listOrder.erase(order_it++);
912  iqStats.statIssuedInstType[tid][op_class]++;
913  } else {
914  iqStats.statFuBusy[op_class]++;
915  iqStats.fuBusy[tid]++;
916  ++order_it;
917  }
918  }
919 
920  iqStats.numIssuedDist.sample(total_issued);
921  iqStats.instsIssued+= total_issued;
922 
923  // If we issued any instructions, tell the CPU we had activity.
924  // @todo If the way deferred memory instructions are handeled due to
925  // translation changes then the deferredMemInsts condition should be removed
926  // from the code below.
927  if (total_issued || !retryMemInsts.empty() || !deferredMemInsts.empty()) {
928  cpu->activityThisCycle();
929  } else {
930  DPRINTF(IQ, "Not able to schedule any instructions.\n");
931  }
932 }
933 
934 template <class Impl>
935 void
937 {
938  DPRINTF(IQ, "Marking nonspeculative instruction [sn:%llu] as ready "
939  "to execute.\n", inst);
940 
941  NonSpecMapIt inst_it = nonSpecInsts.find(inst);
942 
943  assert(inst_it != nonSpecInsts.end());
944 
945  ThreadID tid = (*inst_it).second->threadNumber;
946 
947  (*inst_it).second->setAtCommit();
948 
949  (*inst_it).second->setCanIssue();
950 
951  if (!(*inst_it).second->isMemRef()) {
952  addIfReady((*inst_it).second);
953  } else {
954  memDepUnit[tid].nonSpecInstReady((*inst_it).second);
955  }
956 
957  (*inst_it).second = NULL;
958 
959  nonSpecInsts.erase(inst_it);
960 }
961 
962 template <class Impl>
963 void
965 {
966  DPRINTF(IQ, "[tid:%i] Committing instructions older than [sn:%llu]\n",
967  tid,inst);
968 
969  ListIt iq_it = instList[tid].begin();
970 
971  while (iq_it != instList[tid].end() &&
972  (*iq_it)->seqNum <= inst) {
973  ++iq_it;
974  instList[tid].pop_front();
975  }
976 
977  assert(freeEntries == (numEntries - countInsts()));
978 }
979 
980 template <class Impl>
981 int
983 {
984  int dependents = 0;
985 
986  // The instruction queue here takes care of both floating and int ops
987  if (completed_inst->isFloating()) {
989  } else if (completed_inst->isVector()) {
991  } else {
993  }
994 
995  DPRINTF(IQ, "Waking dependents of completed instruction.\n");
996 
997  assert(!completed_inst->isSquashed());
998 
999  // Tell the memory dependence unit to wake any dependents on this
1000  // instruction if it is a memory instruction. Also complete the memory
1001  // instruction at this point since we know it executed without issues.
1002  ThreadID tid = completed_inst->threadNumber;
1003  if (completed_inst->isMemRef()) {
1004  memDepUnit[tid].completeInst(completed_inst);
1005 
1006  DPRINTF(IQ, "Completing mem instruction PC: %s [sn:%llu]\n",
1007  completed_inst->pcState(), completed_inst->seqNum);
1008 
1009  ++freeEntries;
1010  completed_inst->memOpDone(true);
1011  count[tid]--;
1012  } else if (completed_inst->isReadBarrier() ||
1013  completed_inst->isWriteBarrier()) {
1014  // Completes a non mem ref barrier
1015  memDepUnit[tid].completeInst(completed_inst);
1016  }
1017 
1018  for (int dest_reg_idx = 0;
1019  dest_reg_idx < completed_inst->numDestRegs();
1020  dest_reg_idx++)
1021  {
1022  PhysRegIdPtr dest_reg =
1023  completed_inst->regs.renamedDestIdx(dest_reg_idx);
1024 
1025  // Special case of uniq or control registers. They are not
1026  // handled by the IQ and thus have no dependency graph entry.
1027  if (dest_reg->isFixedMapping()) {
1028  DPRINTF(IQ, "Reg %d [%s] is part of a fix mapping, skipping\n",
1029  dest_reg->index(), dest_reg->className());
1030  continue;
1031  }
1032 
1033  // Avoid waking up dependents if the register is pinned
1034  dest_reg->decrNumPinnedWritesToComplete();
1035  if (dest_reg->isPinned())
1036  completed_inst->setPinnedRegsWritten();
1037 
1038  if (dest_reg->getNumPinnedWritesToComplete() != 0) {
1039  DPRINTF(IQ, "Reg %d [%s] is pinned, skipping\n",
1040  dest_reg->index(), dest_reg->className());
1041  continue;
1042  }
1043 
1044  DPRINTF(IQ, "Waking any dependents on register %i (%s).\n",
1045  dest_reg->index(),
1046  dest_reg->className());
1047 
1048  //Go through the dependency chain, marking the registers as
1049  //ready within the waiting instructions.
1050  DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIndex());
1051 
1052  while (dep_inst) {
1053  DPRINTF(IQ, "Waking up a dependent instruction, [sn:%llu] "
1054  "PC %s.\n", dep_inst->seqNum, dep_inst->pcState());
1055 
1056  // Might want to give more information to the instruction
1057  // so that it knows which of its source registers is
1058  // ready. However that would mean that the dependency
1059  // graph entries would need to hold the src_reg_idx.
1060  dep_inst->markSrcRegReady();
1061 
1062  addIfReady(dep_inst);
1063 
1064  dep_inst = dependGraph.pop(dest_reg->flatIndex());
1065 
1066  ++dependents;
1067  }
1068 
1069  // Reset the head node now that all of its dependents have
1070  // been woken up.
1071  assert(dependGraph.empty(dest_reg->flatIndex()));
1072  dependGraph.clearInst(dest_reg->flatIndex());
1073 
1074  // Mark the scoreboard as having that register ready.
1075  regScoreboard[dest_reg->flatIndex()] = true;
1076  }
1077  return dependents;
1078 }
1079 
1080 template <class Impl>
1081 void
1083 {
1084  OpClass op_class = ready_inst->opClass();
1085 
1086  readyInsts[op_class].push(ready_inst);
1087 
1088  // Will need to reorder the list if either a queue is not on the list,
1089  // or it has an older instruction than last time.
1090  if (!queueOnList[op_class]) {
1091  addToOrderList(op_class);
1092  } else if (readyInsts[op_class].top()->seqNum <
1093  (*readyIt[op_class]).oldestInst) {
1094  listOrder.erase(readyIt[op_class]);
1095  addToOrderList(op_class);
1096  }
1097 
1098  DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
1099  "the ready list, PC %s opclass:%i [sn:%llu].\n",
1100  ready_inst->pcState(), op_class, ready_inst->seqNum);
1101 }
1102 
1103 template <class Impl>
1104 void
1106 {
1107  DPRINTF(IQ, "Rescheduling mem inst [sn:%llu]\n", resched_inst->seqNum);
1108 
1109  // Reset DTB translation state
1110  resched_inst->translationStarted(false);
1111  resched_inst->translationCompleted(false);
1112 
1113  resched_inst->clearCanIssue();
1114  memDepUnit[resched_inst->threadNumber].reschedule(resched_inst);
1115 }
1116 
1117 template <class Impl>
1118 void
1120 {
1121  memDepUnit[replay_inst->threadNumber].replay();
1122 }
1123 
1124 template <class Impl>
1125 void
1127 {
1128  deferredMemInsts.push_back(deferred_inst);
1129 }
1130 
1131 template <class Impl>
1132 void
1134 {
1135  blocked_inst->clearIssued();
1136  blocked_inst->clearCanIssue();
1137  blockedMemInsts.push_back(blocked_inst);
1138 }
1139 
1140 template <class Impl>
1141 void
1143 {
1145  // Get the CPU ticking again
1146  cpu->wakeCPU();
1147 }
1148 
1149 template <class Impl>
1150 typename Impl::DynInstPtr
1152 {
1153  for (ListIt it = deferredMemInsts.begin(); it != deferredMemInsts.end();
1154  ++it) {
1155  if ((*it)->translationCompleted() || (*it)->isSquashed()) {
1156  DynInstPtr mem_inst = std::move(*it);
1157  deferredMemInsts.erase(it);
1158  return mem_inst;
1159  }
1160  }
1161  return nullptr;
1162 }
1163 
1164 template <class Impl>
1165 typename Impl::DynInstPtr
1167 {
1168  if (retryMemInsts.empty()) {
1169  return nullptr;
1170  } else {
1171  DynInstPtr mem_inst = std::move(retryMemInsts.front());
1172  retryMemInsts.pop_front();
1173  return mem_inst;
1174  }
1175 }
1176 
1177 template <class Impl>
1178 void
1180  const DynInstPtr &faulting_load)
1181 {
1183  memDepUnit[store->threadNumber].violation(store, faulting_load);
1184 }
1185 
1186 template <class Impl>
1187 void
1189 {
1190  DPRINTF(IQ, "[tid:%i] Starting to squash instructions in "
1191  "the IQ.\n", tid);
1192 
1193  // Read instruction sequence number of last instruction out of the
1194  // time buffer.
1195  squashedSeqNum[tid] = fromCommit->commitInfo[tid].doneSeqNum;
1196 
1197  doSquash(tid);
1198 
1199  // Also tell the memory dependence unit to squash.
1200  memDepUnit[tid].squash(squashedSeqNum[tid], tid);
1201 }
1202 
1203 template <class Impl>
1204 void
1206 {
1207  // Start at the tail.
1208  ListIt squash_it = instList[tid].end();
1209  --squash_it;
1210 
1211  DPRINTF(IQ, "[tid:%i] Squashing until sequence number %i!\n",
1212  tid, squashedSeqNum[tid]);
1213 
1214  // Squash any instructions younger than the squashed sequence number
1215  // given.
1216  while (squash_it != instList[tid].end() &&
1217  (*squash_it)->seqNum > squashedSeqNum[tid]) {
1218 
1219  DynInstPtr squashed_inst = (*squash_it);
1220  if (squashed_inst->isFloating()) {
1222  } else if (squashed_inst->isVector()) {
1224  } else {
1226  }
1227 
1228  // Only handle the instruction if it actually is in the IQ and
1229  // hasn't already been squashed in the IQ.
1230  if (squashed_inst->threadNumber != tid ||
1231  squashed_inst->isSquashedInIQ()) {
1232  --squash_it;
1233  continue;
1234  }
1235 
1236  if (!squashed_inst->isIssued() ||
1237  (squashed_inst->isMemRef() &&
1238  !squashed_inst->memOpDone())) {
1239 
1240  DPRINTF(IQ, "[tid:%i] Instruction [sn:%llu] PC %s squashed.\n",
1241  tid, squashed_inst->seqNum, squashed_inst->pcState());
1242 
1243  bool is_acq_rel = squashed_inst->isFullMemBarrier() &&
1244  (squashed_inst->isLoad() ||
1245  (squashed_inst->isStore() &&
1246  !squashed_inst->isStoreConditional()));
1247 
1248  // Remove the instruction from the dependency list.
1249  if (is_acq_rel ||
1250  (!squashed_inst->isNonSpeculative() &&
1251  !squashed_inst->isStoreConditional() &&
1252  !squashed_inst->isAtomic() &&
1253  !squashed_inst->isReadBarrier() &&
1254  !squashed_inst->isWriteBarrier())) {
1255 
1256  for (int src_reg_idx = 0;
1257  src_reg_idx < squashed_inst->numSrcRegs();
1258  src_reg_idx++)
1259  {
1260  PhysRegIdPtr src_reg =
1261  squashed_inst->regs.renamedSrcIdx(src_reg_idx);
1262 
1263  // Only remove it from the dependency graph if it
1264  // was placed there in the first place.
1265 
1266  // Instead of doing a linked list traversal, we
1267  // can just remove these squashed instructions
1268  // either at issue time, or when the register is
1269  // overwritten. The only downside to this is it
1270  // leaves more room for error.
1271 
1272  if (!squashed_inst->regs.readySrcIdx(src_reg_idx) &&
1273  !src_reg->isFixedMapping()) {
1274  dependGraph.remove(src_reg->flatIndex(),
1275  squashed_inst);
1276  }
1277 
1279  }
1280 
1281  } else if (!squashed_inst->isStoreConditional() ||
1282  !squashed_inst->isCompleted()) {
1283  NonSpecMapIt ns_inst_it =
1284  nonSpecInsts.find(squashed_inst->seqNum);
1285 
1286  // we remove non-speculative instructions from
1287  // nonSpecInsts already when they are ready, and so we
1288  // cannot always expect to find them
1289  if (ns_inst_it == nonSpecInsts.end()) {
1290  // loads that became ready but stalled on a
1291  // blocked cache are alreayd removed from
1292  // nonSpecInsts, and have not faulted
1293  assert(squashed_inst->getFault() != NoFault ||
1294  squashed_inst->isMemRef());
1295  } else {
1296 
1297  (*ns_inst_it).second = NULL;
1298 
1299  nonSpecInsts.erase(ns_inst_it);
1300 
1302  }
1303  }
1304 
1305  // Might want to also clear out the head of the dependency graph.
1306 
1307  // Mark it as squashed within the IQ.
1308  squashed_inst->setSquashedInIQ();
1309 
1310  // @todo: Remove this hack where several statuses are set so the
1311  // inst will flow through the rest of the pipeline.
1312  squashed_inst->setIssued();
1313  squashed_inst->setCanCommit();
1314  squashed_inst->clearInIQ();
1315 
1316  //Update Thread IQ Count
1317  count[squashed_inst->threadNumber]--;
1318 
1319  ++freeEntries;
1320  }
1321 
1322  // IQ clears out the heads of the dependency graph only when
1323  // instructions reach writeback stage. If an instruction is squashed
1324  // before writeback stage, its head of dependency graph would not be
1325  // cleared out; it holds the instruction's DynInstPtr. This prevents
1326  // freeing the squashed instruction's DynInst.
1327  // Thus, we need to manually clear out the squashed instructions' heads
1328  // of dependency graph.
1329  for (int dest_reg_idx = 0;
1330  dest_reg_idx < squashed_inst->numDestRegs();
1331  dest_reg_idx++)
1332  {
1333  PhysRegIdPtr dest_reg =
1334  squashed_inst->regs.renamedDestIdx(dest_reg_idx);
1335  if (dest_reg->isFixedMapping()){
1336  continue;
1337  }
1338  assert(dependGraph.empty(dest_reg->flatIndex()));
1339  dependGraph.clearInst(dest_reg->flatIndex());
1340  }
1341  instList[tid].erase(squash_it--);
1343  }
1344 }
1345 
1346 template <class Impl>
1347 bool
1349 {
1350  // Loop through the instruction's source registers, adding
1351  // them to the dependency list if they are not ready.
1352  int8_t total_src_regs = new_inst->numSrcRegs();
1353  bool return_val = false;
1354 
1355  for (int src_reg_idx = 0;
1356  src_reg_idx < total_src_regs;
1357  src_reg_idx++)
1358  {
1359  // Only add it to the dependency graph if it's not ready.
1360  if (!new_inst->regs.readySrcIdx(src_reg_idx)) {
1361  PhysRegIdPtr src_reg = new_inst->regs.renamedSrcIdx(src_reg_idx);
1362 
1363  // Check the IQ's scoreboard to make sure the register
1364  // hasn't become ready while the instruction was in flight
1365  // between stages. Only if it really isn't ready should
1366  // it be added to the dependency graph.
1367  if (src_reg->isFixedMapping()) {
1368  continue;
1369  } else if (!regScoreboard[src_reg->flatIndex()]) {
1370  DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that "
1371  "is being added to the dependency chain.\n",
1372  new_inst->pcState(), src_reg->index(),
1373  src_reg->className());
1374 
1375  dependGraph.insert(src_reg->flatIndex(), new_inst);
1376 
1377  // Change the return value to indicate that something
1378  // was added to the dependency graph.
1379  return_val = true;
1380  } else {
1381  DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that "
1382  "became ready before it reached the IQ.\n",
1383  new_inst->pcState(), src_reg->index(),
1384  src_reg->className());
1385  // Mark a register ready within the instruction.
1386  new_inst->markSrcRegReady(src_reg_idx);
1387  }
1388  }
1389  }
1390 
1391  return return_val;
1392 }
1393 
1394 template <class Impl>
1395 void
1397 {
1398  // Nothing really needs to be marked when an instruction becomes
1399  // the producer of a register's value, but for convenience a ptr
1400  // to the producing instruction will be placed in the head node of
1401  // the dependency links.
1402  int8_t total_dest_regs = new_inst->numDestRegs();
1403 
1404  for (int dest_reg_idx = 0;
1405  dest_reg_idx < total_dest_regs;
1406  dest_reg_idx++)
1407  {
1408  PhysRegIdPtr dest_reg = new_inst->regs.renamedDestIdx(dest_reg_idx);
1409 
1410  // Some registers have fixed mapping, and there is no need to track
1411  // dependencies as these instructions must be executed at commit.
1412  if (dest_reg->isFixedMapping()) {
1413  continue;
1414  }
1415 
1416  if (!dependGraph.empty(dest_reg->flatIndex())) {
1417  dependGraph.dump();
1418  panic("Dependency graph %i (%s) (flat: %i) not empty!",
1419  dest_reg->index(), dest_reg->className(),
1420  dest_reg->flatIndex());
1421  }
1422 
1423  dependGraph.setInst(dest_reg->flatIndex(), new_inst);
1424 
1425  // Mark the scoreboard to say it's not yet ready.
1426  regScoreboard[dest_reg->flatIndex()] = false;
1427  }
1428 }
1429 
1430 template <class Impl>
1431 void
1433 {
1434  // If the instruction now has all of its source registers
1435  // available, then add it to the list of ready instructions.
1436  if (inst->readyToIssue()) {
1437 
1438  //Add the instruction to the proper ready list.
1439  if (inst->isMemRef()) {
1440 
1441  DPRINTF(IQ, "Checking if memory instruction can issue.\n");
1442 
1443  // Message to the mem dependence unit that this instruction has
1444  // its registers ready.
1445  memDepUnit[inst->threadNumber].regsReady(inst);
1446 
1447  return;
1448  }
1449 
1450  OpClass op_class = inst->opClass();
1451 
1452  DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
1453  "the ready list, PC %s opclass:%i [sn:%llu].\n",
1454  inst->pcState(), op_class, inst->seqNum);
1455 
1456  readyInsts[op_class].push(inst);
1457 
1458  // Will need to reorder the list if either a queue is not on the list,
1459  // or it has an older instruction than last time.
1460  if (!queueOnList[op_class]) {
1461  addToOrderList(op_class);
1462  } else if (readyInsts[op_class].top()->seqNum <
1463  (*readyIt[op_class]).oldestInst) {
1464  listOrder.erase(readyIt[op_class]);
1465  addToOrderList(op_class);
1466  }
1467  }
1468 }
1469 
1470 template <class Impl>
1471 int
1473 {
1474  return numEntries - freeEntries;
1475 }
1476 
1477 template <class Impl>
1478 void
1480 {
1481  for (int i = 0; i < Num_OpClasses; ++i) {
1482  cprintf("Ready list %i size: %i\n", i, readyInsts[i].size());
1483 
1484  cprintf("\n");
1485  }
1486 
1487  cprintf("Non speculative list size: %i\n", nonSpecInsts.size());
1488 
1489  NonSpecMapIt non_spec_it = nonSpecInsts.begin();
1490  NonSpecMapIt non_spec_end_it = nonSpecInsts.end();
1491 
1492  cprintf("Non speculative list: ");
1493 
1494  while (non_spec_it != non_spec_end_it) {
1495  cprintf("%s [sn:%llu]", (*non_spec_it).second->pcState(),
1496  (*non_spec_it).second->seqNum);
1497  ++non_spec_it;
1498  }
1499 
1500  cprintf("\n");
1501 
1502  ListOrderIt list_order_it = listOrder.begin();
1503  ListOrderIt list_order_end_it = listOrder.end();
1504  int i = 1;
1505 
1506  cprintf("List order: ");
1507 
1508  while (list_order_it != list_order_end_it) {
1509  cprintf("%i OpClass:%i [sn:%llu] ", i, (*list_order_it).queueType,
1510  (*list_order_it).oldestInst);
1511 
1512  ++list_order_it;
1513  ++i;
1514  }
1515 
1516  cprintf("\n");
1517 }
1518 
1519 
1520 template <class Impl>
1521 void
1523 {
1524  for (ThreadID tid = 0; tid < numThreads; ++tid) {
1525  int num = 0;
1526  int valid_num = 0;
1527  ListIt inst_list_it = instList[tid].begin();
1528 
1529  while (inst_list_it != instList[tid].end()) {
1530  cprintf("Instruction:%i\n", num);
1531  if (!(*inst_list_it)->isSquashed()) {
1532  if (!(*inst_list_it)->isIssued()) {
1533  ++valid_num;
1534  cprintf("Count:%i\n", valid_num);
1535  } else if ((*inst_list_it)->isMemRef() &&
1536  !(*inst_list_it)->memOpDone()) {
1537  // Loads that have not been marked as executed
1538  // still count towards the total instructions.
1539  ++valid_num;
1540  cprintf("Count:%i\n", valid_num);
1541  }
1542  }
1543 
1544  cprintf("PC: %s\n[sn:%llu]\n[tid:%i]\n"
1545  "Issued:%i\nSquashed:%i\n",
1546  (*inst_list_it)->pcState(),
1547  (*inst_list_it)->seqNum,
1548  (*inst_list_it)->threadNumber,
1549  (*inst_list_it)->isIssued(),
1550  (*inst_list_it)->isSquashed());
1551 
1552  if ((*inst_list_it)->isMemRef()) {
1553  cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone());
1554  }
1555 
1556  cprintf("\n");
1557 
1558  inst_list_it++;
1559  ++num;
1560  }
1561  }
1562 
1563  cprintf("Insts to Execute list:\n");
1564 
1565  int num = 0;
1566  int valid_num = 0;
1567  ListIt inst_list_it = instsToExecute.begin();
1568 
1569  while (inst_list_it != instsToExecute.end())
1570  {
1571  cprintf("Instruction:%i\n",
1572  num);
1573  if (!(*inst_list_it)->isSquashed()) {
1574  if (!(*inst_list_it)->isIssued()) {
1575  ++valid_num;
1576  cprintf("Count:%i\n", valid_num);
1577  } else if ((*inst_list_it)->isMemRef() &&
1578  !(*inst_list_it)->memOpDone()) {
1579  // Loads that have not been marked as executed
1580  // still count towards the total instructions.
1581  ++valid_num;
1582  cprintf("Count:%i\n", valid_num);
1583  }
1584  }
1585 
1586  cprintf("PC: %s\n[sn:%llu]\n[tid:%i]\n"
1587  "Issued:%i\nSquashed:%i\n",
1588  (*inst_list_it)->pcState(),
1589  (*inst_list_it)->seqNum,
1590  (*inst_list_it)->threadNumber,
1591  (*inst_list_it)->isIssued(),
1592  (*inst_list_it)->isSquashed());
1593 
1594  if ((*inst_list_it)->isMemRef()) {
1595  cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone());
1596  }
1597 
1598  cprintf("\n");
1599 
1600  inst_list_it++;
1601  ++num;
1602  }
1603 }
1604 
1605 #endif//__CPU_O3_INST_QUEUE_IMPL_HH__
InstructionQueue::IQStats::instsIssued
Stats::Scalar instsIssued
Definition: inst_queue.hh:480
Num_OpClasses
static const OpClass Num_OpClasses
Definition: op_class.hh:105
InstructionQueue::nonSpecInsts
std::map< InstSeqNum, DynInstPtr > nonSpecInsts
List of non-speculative instructions that will be scheduled once the IQ gets a signal from commit.
Definition: inst_queue.hh:356
InstructionQueue::IQIOStats::fpInstQueueWakeupAccesses
Stats::Scalar fpInstQueueWakeupAccesses
Definition: inst_queue.hh:544
InstructionQueue::addIfReady
void addIfReady(const DynInstPtr &inst)
Moves an instruction to the ready queue if it is ready.
Definition: inst_queue_impl.hh:1432
InstructionQueue::IQStats::issueRate
Stats::Formula issueRate
Number of instructions issued per cycle.
Definition: inst_queue.hh:527
InstructionQueue::ListOrderEntry::queueType
OpClass queueType
Definition: inst_queue.hh:362
InstructionQueue::ListOrderEntry::oldestInst
InstSeqNum oldestInst
Definition: inst_queue.hh:363
InstructionQueue::takeOverFrom
void takeOverFrom()
Takes over execution from another CPU's thread.
Definition: inst_queue_impl.hh:475
MemDepUnit::replay
void replay()
Replays all instructions that have been rescheduled by moving them to the ready list.
Definition: mem_dep_unit_impl.hh:403
InstructionQueue::iqIOStats
InstructionQueue::IQIOStats iqIOStats
InstructionQueue::iewStage
IEW * iewStage
Pointer to IEW stage.
Definition: inst_queue.hh:283
InstructionQueue::wakeDependents
int wakeDependents(const DynInstPtr &completed_inst)
Wakes all dependents of a completed instruction.
Definition: inst_queue_impl.hh:982
InstructionQueue::commit
void commit(const InstSeqNum &inst, ThreadID tid=0)
Commits all instructions up to and including the given sequence number, for a specific thread.
Definition: inst_queue_impl.hh:964
InstructionQueue::FUCompletion::setFreeFU
void setFreeFU()
Definition: inst_queue.hh:120
InstructionQueue::readyInsts
ReadyInstQueue readyInsts[Num_OpClasses]
List of ready instructions, per op class.
Definition: inst_queue.hh:347
InstructionQueue::name
std::string name() const
Returns the name of the IQ.
Definition: inst_queue_impl.hh:171
MemDepUnit::nonSpecInstReady
void nonSpecInstReady(const DynInstPtr &inst)
Indicate that a non-speculative instruction is ready.
Definition: mem_dep_unit_impl.hh:383
InstructionQueue::fromCommit
TimeBuffer< TimeStruct >::wire fromCommit
Wire to read information from timebuffer.
Definition: inst_queue.hh:299
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
InstructionQueue::getDeferredMemInstToExecute
DynInstPtr getDeferredMemInstToExecute()
Gets a memory instruction that was referred due to a delayed DTB translation if it is now ready to ex...
Definition: inst_queue_impl.hh:1151
InstructionQueue::squash
void squash(ThreadID tid)
Squashes instructions for a thread.
Definition: inst_queue_impl.hh:1188
InstructionQueue::getBlockedMemInstToExecute
DynInstPtr getBlockedMemInstToExecute()
Gets a memory instruction that was blocked on the cache.
Definition: inst_queue_impl.hh:1166
InstructionQueue::count
unsigned count[Impl::MaxThreads]
Per Thread IQ count.
Definition: inst_queue.hh:410
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:233
InstructionQueue::timeBuffer
TimeBuffer< TimeStruct > * timeBuffer
The backwards time buffer.
Definition: inst_queue.hh:296
InstructionQueue::FUCompletion::process
virtual void process()
Definition: inst_queue_impl.hh:70
InstructionQueue::commitToIEWDelay
Cycles commitToIEWDelay
Delay between commit stage and the IQ.
Definition: inst_queue.hh:433
InstructionQueue::iqPolicy
SMTQueuePolicy iqPolicy
IQ sharing policy for SMT.
Definition: inst_queue.hh:401
InstructionQueue::ListOrderIt
std::list< ListOrderEntry >::iterator ListOrderIt
Definition: inst_queue.hh:375
InstructionQueue::resetEntries
void resetEntries()
Resets max entries for all threads.
Definition: inst_queue_impl.hh:494
InstructionQueue::IQStats::memInstsIssued
Stats::Scalar memInstsIssued
Stat for number of memory instructions issued.
Definition: inst_queue.hh:488
InstructionQueue::retryMemInsts
std::list< DynInstPtr > retryMemInsts
List of instructions that were cache blocked, but a retry has been seen since, so they can now be ret...
Definition: inst_queue.hh:325
PhysRegId::flatIndex
const PhysRegIndex & flatIndex() const
Flat index accessor.
Definition: reg_class.hh:309
InstructionQueue::InstructionQueue
InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr, const DerivO3CPUParams &params)
Constructs an IQ.
Definition: inst_queue_impl.hh:85
InstructionQueue::resetState
void resetState()
Resets all instruction queue state.
Definition: inst_queue_impl.hh:389
sc_dt::list
static scfx_rep_node * list
Definition: scfx_rep.cc:368
InstructionQueue::entryAmount
int entryAmount(ThreadID num_threads)
Number of entries needed for given amount of threads.
Definition: inst_queue_impl.hh:482
MemDepUnit::issue
void issue(const DynInstPtr &inst)
Issues the given instruction.
Definition: mem_dep_unit_impl.hh:581
InstructionQueue::deferMemInst
void deferMemInst(const DynInstPtr &deferred_inst)
Defers a memory instruction when its DTB translation incurs a hw page table walk.
Definition: inst_queue_impl.hh:1126
FUPool::getUnit
int getUnit(OpClass capability)
Gets a FU providing the requested capability.
Definition: fu_pool.cc:156
InstructionQueue::NonSpecMapIt
std::map< InstSeqNum, DynInstPtr >::iterator NonSpecMapIt
Definition: inst_queue.hh:358
top
Definition: test.h:61
InstructionQueue::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: inst_queue_impl.hh:465
InstructionQueue::~InstructionQueue
~InstructionQueue()
Destructs the IQ.
Definition: inst_queue_impl.hh:160
InstructionQueue::IQStats::statFuBusy
Stats::Vector statFuBusy
Distribution of the cycles it takes to issue an instruction.
Definition: inst_queue.hh:521
InstructionQueue::countInsts
int countInsts()
Debugging function to count how many entries are in the IQ.
Definition: inst_queue_impl.hh:1472
InstructionQueue::dependGraph
DependencyGraph< DynInstPtr > dependGraph
Definition: inst_queue.hh:394
InstructionQueue::ListIt
std::list< DynInstPtr >::iterator ListIt
Definition: inst_queue.hh:94
InstructionQueue::maxEntries
unsigned maxEntries[Impl::MaxThreads]
Max IQ Entries Per Thread.
Definition: inst_queue.hh:413
InstructionQueue::blockMemInst
void blockMemInst(const DynInstPtr &blocked_inst)
Defers a memory instruction when it is cache blocked.
Definition: inst_queue_impl.hh:1133
PhysRegId::isFixedMapping
bool isFixedMapping() const
Returns true if this register is always associated to the same architectural register.
Definition: reg_class.hh:306
InstructionQueue::IQStats::intInstsIssued
Stats::Scalar intInstsIssued
Stat for number of integer instructions issued.
Definition: inst_queue.hh:482
InstructionQueue::moveToYoungerInst
void moveToYoungerInst(ListOrderIt age_order_it)
Called when the oldest instruction has been removed from a ready queue; this places that ready queue ...
Definition: inst_queue_impl.hh:718
InstructionQueue::cacheUnblocked
void cacheUnblocked()
Notify instruction queue that a previous blockage has resolved.
Definition: inst_queue_impl.hh:1142
MemDepUnit::completeInst
void completeInst(const DynInstPtr &inst)
Notifies completion of an instruction.
Definition: mem_dep_unit_impl.hh:448
InstructionQueue::IQStats::squashedInstsIssued
Stats::Scalar squashedInstsIssued
Stat for number of squashed instructions that were ready to issue.
Definition: inst_queue.hh:493
InstructionQueue::setIssueToExecuteQueue
void setIssueToExecuteQueue(TimeBuffer< IssueStruct > *i2eQueue)
Sets the timer buffer between issue and execute.
Definition: inst_queue_impl.hh:436
InstructionQueue::numPhysRegs
unsigned numPhysRegs
The number of physical registers in the CPU.
Definition: inst_queue.hh:425
TimeBuffer< IssueStruct >
InstructionQueue::readyIt
ListOrderIt readyIt[Num_OpClasses]
Iterators of each ready queue.
Definition: inst_queue.hh:383
InstructionQueue::IQIOStats::intInstQueueWakeupAccesses
Stats::Scalar intInstQueueWakeupAccesses
Definition: inst_queue.hh:541
InstructionQueue::processFUCompletion
void processFUCompletion(const DynInstPtr &inst, int fu_idx)
Process FU completion event.
Definition: inst_queue_impl.hh:744
MemDepUnit::violation
void violation(const DynInstPtr &store_inst, const DynInstPtr &violating_load)
Indicates an ordering violation between a store and a younger load.
Definition: mem_dep_unit_impl.hh:569
Stats::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:339
InstructionQueue::cpu
O3CPU * cpu
Pointer to the CPU.
Definition: inst_queue.hh:277
Stats::DataWrapVec2d::ysubnames
Derived & ysubnames(const char **names)
Definition: statistics.hh:459
InstructionQueue::IQIOStats::vecInstQueueWakeupAccesses
Stats::Scalar vecInstQueueWakeupAccesses
Definition: inst_queue.hh:547
InstructionQueue::IQIOStats::vecInstQueueReads
Stats::Scalar vecInstQueueReads
Definition: inst_queue.hh:545
InstructionQueue::fuPool
FUPool * fuPool
Function unit pool.
Definition: inst_queue.hh:302
InstructionQueue::deferredMemInsts
std::list< DynInstPtr > deferredMemInsts
List of instructions waiting for their DTB translation to complete (hw page table walk in progress).
Definition: inst_queue.hh:317
InstructionQueue::IQStats::nonSpecInstsAdded
Stats::Scalar nonSpecInstsAdded
Stat for number of non-speculative instructions added.
Definition: inst_queue.hh:478
PhysRegId::index
const RegIndex & index() const
Visible RegId methods.
Definition: reg_class.hh:171
InstructionQueue::totalWidth
unsigned totalWidth
The total number of instructions that can be issued in one cycle.
Definition: inst_queue.hh:422
InstructionQueue::IQStats::floatInstsIssued
Stats::Scalar floatInstsIssued
Stat for number of floating point instructions issued.
Definition: inst_queue.hh:484
MemDepUnit::squash
void squash(const InstSeqNum &squashed_num, ThreadID tid)
Squashes all instructions up until a given sequence number for a specific thread.
Definition: mem_dep_unit_impl.hh:517
InstructionQueue::ListOrderEntry
Entry for the list age ordering by op class.
Definition: inst_queue.hh:361
IssueStruct::size
int size
Definition: comm.hh:108
MemDepUnit::insertNonSpec
void insertNonSpec(const DynInstPtr &inst)
Inserts a non-speculative memory instruction.
Definition: mem_dep_unit_impl.hh:315
FUPool::NoCapableFU
static constexpr auto NoCapableFU
Definition: fu_pool.hh:135
Stats::DataWrap::prereq
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:353
Event
Definition: eventq.hh:248
InstructionQueue::memDepUnit
MemDepUnit memDepUnit[Impl::MaxThreads]
The memory dependence unit, which tracks/predicts memory dependences between instructions.
Definition: inst_queue.hh:288
MemDepUnit::init
void init(const DerivO3CPUParams &params, ThreadID tid, O3CPU *cpu)
Initializes the unit with parameters and a thread id.
Definition: mem_dep_unit_impl.hh:99
InstructionQueue::insert
void insert(const DynInstPtr &new_inst)
Inserts a new instruction into the IQ.
Definition: inst_queue_impl.hh:572
cprintf
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:152
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
InstructionQueue::addToProducers
void addToProducers(const DynInstPtr &new_inst)
Adds an instruction to the dependency graph, as a producer.
Definition: inst_queue_impl.hh:1396
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
TimeBuffer::access
T * access(int idx)
Definition: timebuf.hh:208
InstructionQueue::IQStats::instsAdded
Stats::Scalar instsAdded
Stat for number of instructions added.
Definition: inst_queue.hh:476
InstructionQueue::activeThreads
std::list< ThreadID > * activeThreads
Pointer to list of active threads.
Definition: inst_queue.hh:407
InstructionQueue::isDrained
bool isDrained() const
Determine if we are drained.
Definition: inst_queue_impl.hh:452
InstructionQueue::dumpLists
void dumpLists()
Debugging function to dump all the list sizes, as well as print out the list of nonspeculative instru...
Definition: inst_queue_impl.hh:1479
InstructionQueue::freeEntries
unsigned freeEntries
Number of free IQ entries left.
Definition: inst_queue.hh:416
InstructionQueue::numThreads
ThreadID numThreads
Number of Total Threads.
Definition: inst_queue.hh:404
MemDepUnit::reschedule
void reschedule(const DynInstPtr &inst)
Reschedules an instruction to be re-executed.
Definition: mem_dep_unit_impl.hh:396
ArmISA::NumVecElemPerVecReg
constexpr unsigned NumVecElemPerVecReg
Definition: registers.hh:58
InstructionQueue::iqStats
InstructionQueue::IQStats iqStats
IssueStruct
Definition: comm.hh:105
InstructionQueue::IQStats::fuBusyRate
Stats::Formula fuBusyRate
Number of times the FU was busy per instruction issued.
Definition: inst_queue.hh:532
InstructionQueue::wbOutstanding
int wbOutstanding
Number of instructions currently in flight to FUs.
Definition: inst_queue.hh:428
InstructionQueue::IQStats::squashedOperandsExamined
Stats::Scalar squashedOperandsExamined
Stat for number of squashed instruction operands examined when squashing.
Definition: inst_queue.hh:500
fu_pool.hh
InstructionQueue::replayMemInst
void replayMemInst(const DynInstPtr &replay_inst)
Replays a memory instruction.
Definition: inst_queue_impl.hh:1119
InstructionQueue::IQIOStats::fpInstQueueWrites
Stats::Scalar fpInstQueueWrites
Definition: inst_queue.hh:543
InstructionQueue::dumpInsts
void dumpInsts()
Debugging function to dump out all instructions that are in the IQ.
Definition: inst_queue_impl.hh:1522
InstructionQueue::insertNonSpec
void insertNonSpec(const DynInstPtr &new_inst)
Inserts a new, non-speculative instruction into the IQ.
Definition: inst_queue_impl.hh:618
InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:37
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:251
InstructionQueue::doSquash
void doSquash(ThreadID tid)
Does the actual squashing.
Definition: inst_queue_impl.hh:1205
InstructionQueue::instsToExecute
std::list< DynInstPtr > instsToExecute
List of instructions that are ready to be executed.
Definition: inst_queue.hh:312
MemDepUnit::setIQ
void setIQ(InstructionQueue< Impl > *iq_ptr)
Sets the pointer to the IQ.
Definition: mem_dep_unit_impl.hh:164
PhysRegId::decrNumPinnedWritesToComplete
void decrNumPinnedWritesToComplete()
Definition: reg_class.hh:350
InstructionQueue::scheduleReadyInsts
void scheduleReadyInsts()
Schedules ready instructions, adding the ready ones (oldest first) to the queue to execute.
Definition: inst_queue_impl.hh:768
core.hh
InstructionQueue::DynInstPtr
Impl::DynInstPtr DynInstPtr
Definition: inst_queue.hh:86
Stats::dist
const FlagsType dist
Print the distribution.
Definition: info.hh:56
InstructionQueue::squashedSeqNum
InstSeqNum squashedSeqNum[Impl::MaxThreads]
The sequence number of the squashed instruction.
Definition: inst_queue.hh:436
Stats::VectorBase::init
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1028
InstructionQueue::scheduleNonSpec
void scheduleNonSpec(const InstSeqNum &inst)
Schedules a single specific non-speculative instruction.
Definition: inst_queue_impl.hh:936
InstructionQueue::violation
void violation(const DynInstPtr &store, const DynInstPtr &faulting_load)
Indicates an ordering violation between a store and a load.
Definition: inst_queue_impl.hh:1179
MemDepUnit::insertBarrier
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a barrier instruction.
Definition: mem_dep_unit_impl.hh:337
InstructionQueue::IEW
Impl::CPUPol::IEW IEW
Definition: inst_queue.hh:88
InstructionQueue::FUCompletion::FUCompletion
FUCompletion(const DynInstPtr &_inst, int fu_idx, InstructionQueue< Impl > *iq_ptr)
Construct a FU completion event.
Definition: inst_queue_impl.hh:61
InstructionQueue::IQStats::IQStats
IQStats(O3CPU *cpu, const unsigned &total_width)
Definition: inst_queue_impl.hh:178
MemDepUnit::regsReady
void regsReady(const DynInstPtr &inst)
Indicate that an instruction has its registers ready.
Definition: mem_dep_unit_impl.hh:360
InstructionQueue::IQStats::statIssuedInstType
Stats::Vector2d statIssuedInstType
Stat for total number issued for each instruction type.
Definition: inst_queue.hh:524
InstructionQueue::IQStats::miscInstsIssued
Stats::Scalar miscInstsIssued
Stat for number of miscellaneous instructions issued.
Definition: inst_queue.hh:490
InstructionQueue::queueOnList
bool queueOnList[Num_OpClasses]
Tracks if each ready queue is on the age order list.
Definition: inst_queue.hh:378
UNIT_RATE
#define UNIT_RATE(T1, T2)
Definition: units.hh:47
MemDepUnit::insert
void insert(const DynInstPtr &inst)
Inserts a memory instruction.
Definition: mem_dep_unit_impl.hh:204
InstructionQueue::FUCompletion::description
virtual const char * description() const
Return a C string describing the event.
Definition: inst_queue_impl.hh:79
PhysRegId::className
const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:201
InstructionQueue::numEntries
unsigned numEntries
The number of entries in the instruction queue.
Definition: inst_queue.hh:419
PhysRegId::isPinned
bool isPinned() const
Definition: reg_class.hh:336
InstructionQueue::IQStats::numIssuedDist
Stats::Distribution numIssuedDist
Distribution of number of instructions in the queue.
Definition: inst_queue.hh:512
InstructionQueue::IQIOStats::intInstQueueReads
Stats::Scalar intInstQueueReads
Definition: inst_queue.hh:539
InstructionQueue::getInstToExecute
DynInstPtr getInstToExecute()
Returns the oldest scheduled instruction, and removes it from the list of instructions waiting to exe...
Definition: inst_queue_impl.hh:674
Stats::Distribution::init
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
Definition: statistics.hh:2113
InstructionQueue::IQIOStats::fpInstQueueReads
Stats::Scalar fpInstQueueReads
Definition: inst_queue.hh:542
InstructionQueue::IQIOStats::fpAluAccesses
Stats::Scalar fpAluAccesses
Definition: inst_queue.hh:550
Stats::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:52
InstructionQueue::IQStats::fuBusy
Stats::Vector fuBusy
Number of times the FU was busy.
Definition: inst_queue.hh:530
PhysRegId::getNumPinnedWritesToComplete
int getNumPinnedWritesToComplete() const
Definition: reg_class.hh:339
InstructionQueue::IQIOStats::intInstQueueWrites
Stats::Scalar intInstQueueWrites
Definition: inst_queue.hh:540
Stats::Group
Statistics container.
Definition: group.hh:87
InstructionQueue
A standard instruction queue class.
Definition: inst_queue.hh:81
InstructionQueue::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets active threads list.
Definition: inst_queue_impl.hh:429
FUPool::freeUnitNextCycle
void freeUnitNextCycle(int fu_idx)
Frees a FU at the end of this cycle.
Definition: fu_pool.cc:184
InstructionQueue::IQStats::squashedInstsExamined
Stats::Scalar squashedInstsExamined
Stat for number of squashed instructions examined when squashing.
Definition: inst_queue.hh:496
InstructionQueue::addToOrderList
void addToOrderList(OpClass op_class)
Add an op class to the age order list.
Definition: inst_queue_impl.hh:691
InstructionQueue::IQStats::squashedNonSpecRemoved
Stats::Scalar squashedNonSpecRemoved
Stat for number of non-speculative instructions removed due to a squash.
Definition: inst_queue.hh:504
Stats::Vector2dBase::init
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1166
FUPool::isPipelined
bool isPipelined(OpClass capability)
Returns the issue latency of the given capability.
Definition: fu_pool.hh:167
InstructionQueue::insertBarrier
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a memory or write barrier into the IQ to make sure loads and stores are ordered properly.
Definition: inst_queue_impl.hh:665
Stats::DistBase::sample
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1323
logging.hh
Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:79
InstructionQueue::IQIOStats::intAluAccesses
Stats::Scalar intAluAccesses
Definition: inst_queue.hh:549
FUPool::getOpLatency
Cycles getOpLatency(OpClass capability)
Returns the operation execution latency of the given capability.
Definition: fu_pool.hh:162
Stats::DataWrapVec::subname
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
Definition: statistics.hh:383
PhysRegId
Physical register ID.
Definition: reg_class.hh:223
InstructionQueue::instList
std::list< DynInstPtr > instList[Impl::MaxThreads]
List of all the instructions in the IQ (some of which may be issued).
Definition: inst_queue.hh:309
InstructionQueue::regScoreboard
std::vector< bool > regScoreboard
A cache of the recently woken registers.
Definition: inst_queue.hh:444
InstructionQueue::blockedMemInsts
std::list< DynInstPtr > blockedMemInsts
List of instructions that have been cache blocked.
Definition: inst_queue.hh:320
Stats
Definition: statistics.cc:53
inst_queue.hh
InstructionQueue::O3CPU
Impl::O3CPU O3CPU
Definition: inst_queue.hh:85
InstructionQueue::addToDependents
bool addToDependents(const DynInstPtr &new_inst)
Adds an instruction to the dependency graph, as a consumer.
Definition: inst_queue_impl.hh:1348
InstructionQueue::numFreeEntries
unsigned numFreeEntries()
Returns total number of free entries.
Definition: inst_queue_impl.hh:517
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
InstructionQueue::FUCompletion
FU completion event class.
Definition: inst_queue.hh:97
InstructionQueue::IQStats::branchInstsIssued
Stats::Scalar branchInstsIssued
Stat for number of branch instructions issued.
Definition: inst_queue.hh:486
std::list
STL list class.
Definition: stl.hh:51
InstructionQueue::rescheduleMemInst
void rescheduleMemInst(const DynInstPtr &resched_inst)
Reschedules a memory instruction.
Definition: inst_queue_impl.hh:1105
FUPool::NoFreeFU
static constexpr auto NoFreeFU
Definition: fu_pool.hh:136
InstructionQueue::setTimeBuffer
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the global time buffer.
Definition: inst_queue_impl.hh:443
Stats::total
const FlagsType total
Print the total.
Definition: info.hh:50
InstructionQueue::IQIOStats::IQIOStats
IQIOStats(Stats::Group *parent)
Definition: inst_queue_impl.hh:324
InstructionQueue::IQIOStats::vecAluAccesses
Stats::Scalar vecAluAccesses
Definition: inst_queue.hh:551
InstructionQueue::isFull
bool isFull()
Returns whether or not the IQ is full.
Definition: inst_queue_impl.hh:533
InstructionQueue::issueToExecuteQueue
TimeBuffer< IssueStruct > * issueToExecuteQueue
The queue to the execute stage.
Definition: inst_queue.hh:293
InstructionQueue::hasReadyInsts
bool hasReadyInsts()
Returns if there are any ready instructions in the IQ.
Definition: inst_queue_impl.hh:555
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
InstructionQueue::addReadyMemInst
void addReadyMemInst(const DynInstPtr &ready_inst)
Adds a ready memory instruction to the ready list.
Definition: inst_queue_impl.hh:1082
InstructionQueue::IQIOStats::vecInstQueueWrites
Stats::Scalar vecInstQueueWrites
Definition: inst_queue.hh:546
TimeBuffer::getWire
wire getWire(int idx)
Definition: timebuf.hh:229
InstructionQueue::listOrder
std::list< ListOrderEntry > listOrder
List that contains the age order of the oldest instruction of each ready queue.
Definition: inst_queue.hh:373

Generated on Tue Jun 22 2021 15:28:26 for gem5 by doxygen 1.8.17