gem5  v22.1.0.0
fetch.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2014 ARM Limited
3  * Copyright (c) 2012-2013 AMD
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 #include "cpu/o3/fetch.hh"
43 
44 #include <algorithm>
45 #include <cstring>
46 #include <list>
47 #include <map>
48 #include <queue>
49 
50 #include "arch/generic/tlb.hh"
51 #include "base/random.hh"
52 #include "base/types.hh"
53 #include "cpu/base.hh"
54 #include "cpu/exetrace.hh"
55 #include "cpu/nop_static_inst.hh"
56 #include "cpu/o3/cpu.hh"
57 #include "cpu/o3/dyn_inst.hh"
58 #include "cpu/o3/limits.hh"
59 #include "debug/Activity.hh"
60 #include "debug/Drain.hh"
61 #include "debug/Fetch.hh"
62 #include "debug/O3CPU.hh"
63 #include "debug/O3PipeView.hh"
64 #include "mem/packet.hh"
65 #include "params/BaseO3CPU.hh"
66 #include "sim/byteswap.hh"
67 #include "sim/core.hh"
68 #include "sim/eventq.hh"
69 #include "sim/full_system.hh"
70 #include "sim/system.hh"
71 
72 namespace gem5
73 {
74 
75 namespace o3
76 {
77 
79  RequestPort(_cpu->name() + ".icache_port", _cpu), fetch(_fetch)
80 {}
81 
82 
83 Fetch::Fetch(CPU *_cpu, const BaseO3CPUParams &params)
84  : fetchPolicy(params.smtFetchPolicy),
85  cpu(_cpu),
86  branchPred(nullptr),
91  fetchWidth(params.fetchWidth),
92  decodeWidth(params.decodeWidth),
93  retryPkt(NULL),
95  cacheBlkSize(cpu->cacheLineSize()),
99  numThreads(params.numThreads),
100  numFetchingThreads(params.smtNumFetchingThreads),
101  icachePort(this, _cpu),
102  finishTranslationEvent(this), fetchStats(_cpu, this)
103 {
104  if (numThreads > MaxThreads)
105  fatal("numThreads (%d) is larger than compiled limit (%d),\n"
106  "\tincrease MaxThreads in src/cpu/o3/limits.hh\n",
107  numThreads, static_cast<int>(MaxThreads));
108  if (fetchWidth > MaxWidth)
109  fatal("fetchWidth (%d) is larger than compiled limit (%d),\n"
110  "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
111  fetchWidth, static_cast<int>(MaxWidth));
113  fatal("fetch buffer size (%u bytes) is greater than the cache "
114  "block size (%u bytes)\n", fetchBufferSize, cacheBlkSize);
116  fatal("cache block (%u bytes) is not a multiple of the "
117  "fetch buffer (%u bytes)\n", cacheBlkSize, fetchBufferSize);
118 
119  for (int i = 0; i < MaxThreads; i++) {
120  fetchStatus[i] = Idle;
121  decoder[i] = nullptr;
122  pc[i].reset(params.isa[0]->newPCState());
123  fetchOffset[i] = 0;
124  macroop[i] = nullptr;
125  delayedCommit[i] = false;
126  memReq[i] = nullptr;
127  stalls[i] = {false, false};
128  fetchBuffer[i] = NULL;
129  fetchBufferPC[i] = 0;
130  fetchBufferValid[i] = false;
131  lastIcacheStall[i] = 0;
132  issuePipelinedIfetch[i] = false;
133  }
134 
135  branchPred = params.branchPred;
136 
137  for (ThreadID tid = 0; tid < numThreads; tid++) {
138  decoder[tid] = params.decoder[tid];
139  // Create space to buffer the cache line data,
140  // which may not hold the entire cache line.
141  fetchBuffer[tid] = new uint8_t[fetchBufferSize];
142  }
143 
144  // Get the size of an instruction.
146 }
147 
148 std::string Fetch::name() const { return cpu->name() + ".fetch"; }
149 
150 void
152 {
155  "FetchRequest");
156 
157 }
158 
160  : statistics::Group(cpu, "fetch"),
161  ADD_STAT(icacheStallCycles, statistics::units::Cycle::get(),
162  "Number of cycles fetch is stalled on an Icache miss"),
163  ADD_STAT(insts, statistics::units::Count::get(),
164  "Number of instructions fetch has processed"),
165  ADD_STAT(branches, statistics::units::Count::get(),
166  "Number of branches that fetch encountered"),
167  ADD_STAT(predictedBranches, statistics::units::Count::get(),
168  "Number of branches that fetch has predicted taken"),
169  ADD_STAT(cycles, statistics::units::Cycle::get(),
170  "Number of cycles fetch has run and was not squashing or "
171  "blocked"),
172  ADD_STAT(squashCycles, statistics::units::Cycle::get(),
173  "Number of cycles fetch has spent squashing"),
174  ADD_STAT(tlbCycles, statistics::units::Cycle::get(),
175  "Number of cycles fetch has spent waiting for tlb"),
176  ADD_STAT(idleCycles, statistics::units::Cycle::get(),
177  "Number of cycles fetch was idle"),
178  ADD_STAT(blockedCycles, statistics::units::Cycle::get(),
179  "Number of cycles fetch has spent blocked"),
180  ADD_STAT(miscStallCycles, statistics::units::Cycle::get(),
181  "Number of cycles fetch has spent waiting on interrupts, or bad "
182  "addresses, or out of MSHRs"),
183  ADD_STAT(pendingDrainCycles, statistics::units::Cycle::get(),
184  "Number of cycles fetch has spent waiting on pipes to drain"),
185  ADD_STAT(noActiveThreadStallCycles, statistics::units::Cycle::get(),
186  "Number of stall cycles due to no active thread to fetch from"),
187  ADD_STAT(pendingTrapStallCycles, statistics::units::Cycle::get(),
188  "Number of stall cycles due to pending traps"),
189  ADD_STAT(pendingQuiesceStallCycles, statistics::units::Cycle::get(),
190  "Number of stall cycles due to pending quiesce instructions"),
191  ADD_STAT(icacheWaitRetryStallCycles, statistics::units::Cycle::get(),
192  "Number of stall cycles due to full MSHR"),
193  ADD_STAT(cacheLines, statistics::units::Count::get(),
194  "Number of cache lines fetched"),
195  ADD_STAT(icacheSquashes, statistics::units::Count::get(),
196  "Number of outstanding Icache misses that were squashed"),
197  ADD_STAT(tlbSquashes, statistics::units::Count::get(),
198  "Number of outstanding ITLB misses that were squashed"),
199  ADD_STAT(nisnDist, statistics::units::Count::get(),
200  "Number of instructions fetched each cycle (Total)"),
201  ADD_STAT(idleRate, statistics::units::Ratio::get(),
202  "Ratio of cycles fetch was idle",
203  idleCycles / cpu->baseStats.numCycles),
204  ADD_STAT(branchRate, statistics::units::Ratio::get(),
205  "Number of branch fetches per cycle",
206  branches / cpu->baseStats.numCycles),
207  ADD_STAT(rate, statistics::units::Rate<
208  statistics::units::Count, statistics::units::Cycle>::get(),
209  "Number of inst fetches per cycle",
210  insts / cpu->baseStats.numCycles)
211 {
214  insts
215  .prereq(insts);
216  branches
217  .prereq(branches);
220  cycles
221  .prereq(cycles);
224  tlbCycles
225  .prereq(tlbCycles);
226  idleCycles
227  .prereq(idleCycles);
230  cacheLines
231  .prereq(cacheLines);
248  nisnDist
249  .init(/* base value */ 0,
250  /* last value */ fetch->fetchWidth,
251  /* bucket size */ 1)
253  idleRate
254  .prereq(idleRate);
255  branchRate
257  rate
259 }
260 void
262 {
263  timeBuffer = time_buffer;
264 
265  // Create wires to get information from proper places in time buffer.
268  fromIEW = timeBuffer->getWire(-iewToFetchDelay);
270 }
271 
272 void
274 {
275  activeThreads = at_ptr;
276 }
277 
278 void
280 {
281  // Create wire to write information to proper place in fetch time buf.
282  toDecode = ftb_ptr->getWire(0);
283 }
284 
285 void
287 {
288  assert(priorityList.empty());
289  resetStage();
290 
291  // Fetch needs to start fetching instructions at the very beginning,
292  // so it must start up in active state.
293  switchToActive();
294 }
295 
296 void
298 {
299  fetchStatus[tid] = Running;
300  set(pc[tid], cpu->pcState(tid));
301  fetchOffset[tid] = 0;
302  macroop[tid] = NULL;
303  delayedCommit[tid] = false;
304  memReq[tid] = NULL;
305  stalls[tid].decode = false;
306  stalls[tid].drain = false;
307  fetchBufferPC[tid] = 0;
308  fetchBufferValid[tid] = false;
309  fetchQueue[tid].clear();
310 
311  // TODO not sure what to do with priorityList for now
312  // priorityList.push_back(tid);
313 }
314 
315 void
317 {
318  numInst = 0;
319  interruptPending = false;
320  cacheBlocked = false;
321 
322  priorityList.clear();
323 
324  // Setup PC and nextPC with initial state.
325  for (ThreadID tid = 0; tid < numThreads; ++tid) {
326  fetchStatus[tid] = Running;
327  set(pc[tid], cpu->pcState(tid));
328  fetchOffset[tid] = 0;
329  macroop[tid] = NULL;
330 
331  delayedCommit[tid] = false;
332  memReq[tid] = NULL;
333 
334  stalls[tid].decode = false;
335  stalls[tid].drain = false;
336 
337  fetchBufferPC[tid] = 0;
338  fetchBufferValid[tid] = false;
339 
340  fetchQueue[tid].clear();
341 
342  priorityList.push_back(tid);
343  }
344 
345  wroteToTimeBuffer = false;
346  _status = Inactive;
347 }
348 
349 void
351 {
352  ThreadID tid = cpu->contextToThread(pkt->req->contextId());
353 
354  DPRINTF(Fetch, "[tid:%i] Waking up from cache miss.\n", tid);
355  assert(!cpu->switchedOut());
356 
357  // Only change the status if it's still waiting on the icache access
358  // to return.
359  if (fetchStatus[tid] != IcacheWaitResponse ||
360  pkt->req != memReq[tid]) {
362  delete pkt;
363  return;
364  }
365 
366  memcpy(fetchBuffer[tid], pkt->getConstPtr<uint8_t>(), fetchBufferSize);
367  fetchBufferValid[tid] = true;
368 
369  // Wake up the CPU (if it went to sleep and was waiting on
370  // this completion event).
371  cpu->wakeCPU();
372 
373  DPRINTF(Activity, "[tid:%i] Activating fetch due to cache completion\n",
374  tid);
375 
376  switchToActive();
377 
378  // Only switch to IcacheAccessComplete if we're not stalled as well.
379  if (checkStall(tid)) {
380  fetchStatus[tid] = Blocked;
381  } else {
383  }
384 
385  pkt->req->setAccessLatency();
386  cpu->ppInstAccessComplete->notify(pkt);
387  // Reset the mem req to NULL.
388  delete pkt;
389  memReq[tid] = NULL;
390 }
391 
392 void
394 {
395  for (ThreadID i = 0; i < numThreads; ++i) {
396  stalls[i].decode = false;
397  stalls[i].drain = false;
398  }
399 }
400 
401 void
403 {
404  assert(isDrained());
405  assert(retryPkt == NULL);
406  assert(retryTid == InvalidThreadID);
407  assert(!cacheBlocked);
408  assert(!interruptPending);
409 
410  for (ThreadID i = 0; i < numThreads; ++i) {
411  assert(!memReq[i]);
412  assert(fetchStatus[i] == Idle || stalls[i].drain);
413  }
414 
416 }
417 
418 bool
420 {
421  /* Make sure that threads are either idle of that the commit stage
422  * has signaled that draining has completed by setting the drain
423  * stall flag. This effectively forces the pipeline to be disabled
424  * until the whole system is drained (simulation may continue to
425  * drain other components).
426  */
427  for (ThreadID i = 0; i < numThreads; ++i) {
428  // Verify fetch queues are drained
429  if (!fetchQueue[i].empty())
430  return false;
431 
432  // Return false if not idle or drain stalled
433  if (fetchStatus[i] != Idle) {
434  if (fetchStatus[i] == Blocked && stalls[i].drain)
435  continue;
436  else
437  return false;
438  }
439  }
440 
441  /* The pipeline might start up again in the middle of the drain
442  * cycle if the finish translation event is scheduled, so make
443  * sure that's not the case.
444  */
446 }
447 
448 void
450 {
451  assert(cpu->getInstPort().isConnected());
452  resetStage();
453 
454 }
455 
456 void
458 {
459  assert(cpu->isDraining());
460  assert(!stalls[tid].drain);
461  DPRINTF(Drain, "%i: Thread drained.\n", tid);
462  stalls[tid].drain = true;
463 }
464 
465 void
467 {
468  DPRINTF(Fetch, "Waking up from quiesce\n");
469  // Hopefully this is safe
470  // @todo: Allow other threads to wake from quiesce.
471  fetchStatus[0] = Running;
472 }
473 
474 void
476 {
477  if (_status == Inactive) {
478  DPRINTF(Activity, "Activating stage.\n");
479 
481 
482  _status = Active;
483  }
484 }
485 
486 void
488 {
489  if (_status == Active) {
490  DPRINTF(Activity, "Deactivating stage.\n");
491 
493 
494  _status = Inactive;
495  }
496 }
497 
498 void
500 {
501  // Update priority list
502  auto thread_it = std::find(priorityList.begin(), priorityList.end(), tid);
503  if (thread_it != priorityList.end()) {
504  priorityList.erase(thread_it);
505  }
506 }
507 
508 bool
510 {
511  // Do branch prediction check here.
512  // A bit of a misnomer...next_PC is actually the current PC until
513  // this function updates it.
514  bool predict_taken;
515 
516  if (!inst->isControl()) {
517  inst->staticInst->advancePC(next_pc);
518  inst->setPredTarg(next_pc);
519  inst->setPredTaken(false);
520  return false;
521  }
522 
523  ThreadID tid = inst->threadNumber;
524  predict_taken = branchPred->predict(inst->staticInst, inst->seqNum,
525  next_pc, tid);
526 
527  if (predict_taken) {
528  DPRINTF(Fetch, "[tid:%i] [sn:%llu] Branch at PC %#x "
529  "predicted to be taken to %s\n",
530  tid, inst->seqNum, inst->pcState().instAddr(), next_pc);
531  } else {
532  DPRINTF(Fetch, "[tid:%i] [sn:%llu] Branch at PC %#x "
533  "predicted to be not taken\n",
534  tid, inst->seqNum, inst->pcState().instAddr());
535  }
536 
537  DPRINTF(Fetch, "[tid:%i] [sn:%llu] Branch at PC %#x "
538  "predicted to go to %s\n",
539  tid, inst->seqNum, inst->pcState().instAddr(), next_pc);
540  inst->setPredTarg(next_pc);
541  inst->setPredTaken(predict_taken);
542 
544 
545  if (predict_taken) {
547  }
548 
549  return predict_taken;
550 }
551 
552 bool
554 {
555  Fault fault = NoFault;
556 
557  assert(!cpu->switchedOut());
558 
559  // @todo: not sure if these should block translation.
560  //AlphaDep
561  if (cacheBlocked) {
562  DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n",
563  tid);
564  return false;
565  } else if (checkInterrupt(pc) && !delayedCommit[tid]) {
566  // Hold off fetch from getting new instructions when:
567  // Cache is blocked, or
568  // while an interrupt is pending and we're not in PAL mode, or
569  // fetch is switched out.
570  DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n",
571  tid);
572  return false;
573  }
574 
575  // Align the fetch address to the start of a fetch buffer segment.
576  Addr fetchBufferBlockPC = fetchBufferAlignPC(vaddr);
577 
578  DPRINTF(Fetch, "[tid:%i] Fetching cache line %#x for addr %#x\n",
579  tid, fetchBufferBlockPC, vaddr);
580 
581  // Setup the memReq to do a read of the first instruction's address.
582  // Set the appropriate read size and flags as well.
583  // Build request here.
584  RequestPtr mem_req = std::make_shared<Request>(
585  fetchBufferBlockPC, fetchBufferSize,
587  cpu->thread[tid]->contextId());
588 
589  mem_req->taskId(cpu->taskId());
590 
591  memReq[tid] = mem_req;
592 
593  // Initiate translation of the icache block
594  fetchStatus[tid] = ItlbWait;
595  FetchTranslation *trans = new FetchTranslation(this);
596  cpu->mmu->translateTiming(mem_req, cpu->thread[tid]->getTC(),
597  trans, BaseMMU::Execute);
598  return true;
599 }
600 
601 void
602 Fetch::finishTranslation(const Fault &fault, const RequestPtr &mem_req)
603 {
604  ThreadID tid = cpu->contextToThread(mem_req->contextId());
605  Addr fetchBufferBlockPC = mem_req->getVaddr();
606 
607  assert(!cpu->switchedOut());
608 
609  // Wake up CPU if it was idle
610  cpu->wakeCPU();
611 
612  if (fetchStatus[tid] != ItlbWait || mem_req != memReq[tid] ||
613  mem_req->getVaddr() != memReq[tid]->getVaddr()) {
614  DPRINTF(Fetch, "[tid:%i] Ignoring itlb completed after squash\n",
615  tid);
617  return;
618  }
619 
620 
621  // If translation was successful, attempt to read the icache block.
622  if (fault == NoFault) {
623  // Check that we're not going off into random memory
624  // If we have, just wait around for commit to squash something and put
625  // us on the right track
626  if (!cpu->system->isMemAddr(mem_req->getPaddr())) {
627  warn("Address %#x is outside of physical memory, stopping fetch\n",
628  mem_req->getPaddr());
629  fetchStatus[tid] = NoGoodAddr;
630  memReq[tid] = NULL;
631  return;
632  }
633 
634  // Build packet here.
635  PacketPtr data_pkt = new Packet(mem_req, MemCmd::ReadReq);
636  data_pkt->dataDynamic(new uint8_t[fetchBufferSize]);
637 
638  fetchBufferPC[tid] = fetchBufferBlockPC;
639  fetchBufferValid[tid] = false;
640  DPRINTF(Fetch, "Fetch: Doing instruction read.\n");
641 
643 
644  // Access the cache.
645  if (!icachePort.sendTimingReq(data_pkt)) {
646  assert(retryPkt == NULL);
647  assert(retryTid == InvalidThreadID);
648  DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
649 
651  retryPkt = data_pkt;
652  retryTid = tid;
653  cacheBlocked = true;
654  } else {
655  DPRINTF(Fetch, "[tid:%i] Doing Icache access.\n", tid);
656  DPRINTF(Activity, "[tid:%i] Activity: Waiting on I-cache "
657  "response.\n", tid);
658  lastIcacheStall[tid] = curTick();
660  // Notify Fetch Request probe when a packet containing a fetch
661  // request is successfully sent
662  ppFetchRequestSent->notify(mem_req);
663  }
664  } else {
665  // Don't send an instruction to decode if we can't handle it.
666  if (!(numInst < fetchWidth) ||
667  !(fetchQueue[tid].size() < fetchQueueSize)) {
672  cpu->clockEdge(Cycles(1)));
673  return;
674  }
675  DPRINTF(Fetch,
676  "[tid:%i] Got back req with addr %#x but expected %#x\n",
677  tid, mem_req->getVaddr(), memReq[tid]->getVaddr());
678  // Translation faulted, icache request won't be sent.
679  memReq[tid] = NULL;
680 
681  // Send the fault to commit. This thread will not do anything
682  // until commit handles the fault. The only other way it can
683  // wake up is if a squash comes along and changes the PC.
684  const PCStateBase &fetch_pc = *pc[tid];
685 
686  DPRINTF(Fetch, "[tid:%i] Translation faulted, building noop.\n", tid);
687  // We will use a nop in ordier to carry the fault.
688  DynInstPtr instruction = buildInst(tid, nopStaticInstPtr, nullptr,
689  fetch_pc, fetch_pc, false);
690  instruction->setNotAnInst();
691 
692  instruction->setPredTarg(fetch_pc);
693  instruction->fault = fault;
694  wroteToTimeBuffer = true;
695 
696  DPRINTF(Activity, "Activity this cycle.\n");
698 
699  fetchStatus[tid] = TrapPending;
700 
701  DPRINTF(Fetch, "[tid:%i] Blocked, need to handle the trap.\n", tid);
702  DPRINTF(Fetch, "[tid:%i] fault (%s) detected @ PC %s.\n",
703  tid, fault->name(), *pc[tid]);
704  }
706 }
707 
708 void
709 Fetch::doSquash(const PCStateBase &new_pc, const DynInstPtr squashInst,
710  ThreadID tid)
711 {
712  DPRINTF(Fetch, "[tid:%i] Squashing, setting PC to: %s.\n",
713  tid, new_pc);
714 
715  set(pc[tid], new_pc);
716  fetchOffset[tid] = 0;
717  if (squashInst && squashInst->pcState().instAddr() == new_pc.instAddr())
718  macroop[tid] = squashInst->macroop;
719  else
720  macroop[tid] = NULL;
721  decoder[tid]->reset();
722 
723  // Clear the icache miss if it's outstanding.
724  if (fetchStatus[tid] == IcacheWaitResponse) {
725  DPRINTF(Fetch, "[tid:%i] Squashing outstanding Icache miss.\n",
726  tid);
727  memReq[tid] = NULL;
728  } else if (fetchStatus[tid] == ItlbWait) {
729  DPRINTF(Fetch, "[tid:%i] Squashing outstanding ITLB miss.\n",
730  tid);
731  memReq[tid] = NULL;
732  }
733 
734  // Get rid of the retrying packet if it was from this thread.
735  if (retryTid == tid) {
736  assert(cacheBlocked);
737  if (retryPkt) {
738  delete retryPkt;
739  }
740  retryPkt = NULL;
742  }
743 
744  fetchStatus[tid] = Squashing;
745 
746  // Empty fetch queue
747  fetchQueue[tid].clear();
748 
749  // microops are being squashed, it is not known wheather the
750  // youngest non-squashed microop was marked delayed commit
751  // or not. Setting the flag to true ensures that the
752  // interrupts are not handled when they cannot be, though
753  // some opportunities to handle interrupts may be missed.
754  delayedCommit[tid] = true;
755 
757 }
758 
759 void
760 Fetch::squashFromDecode(const PCStateBase &new_pc, const DynInstPtr squashInst,
761  const InstSeqNum seq_num, ThreadID tid)
762 {
763  DPRINTF(Fetch, "[tid:%i] Squashing from decode.\n", tid);
764 
765  doSquash(new_pc, squashInst, tid);
766 
767  // Tell the CPU to remove any instructions that are in flight between
768  // fetch and decode.
769  cpu->removeInstsUntil(seq_num, tid);
770 }
771 
772 bool
774 {
775  bool ret_val = false;
776 
777  if (stalls[tid].drain) {
778  assert(cpu->isDraining());
779  DPRINTF(Fetch,"[tid:%i] Drain stall detected.\n",tid);
780  ret_val = true;
781  }
782 
783  return ret_val;
784 }
785 
788 {
789  //Check Running
790  std::list<ThreadID>::iterator threads = activeThreads->begin();
792 
793  while (threads != end) {
794  ThreadID tid = *threads++;
795 
796  if (fetchStatus[tid] == Running ||
797  fetchStatus[tid] == Squashing ||
799 
800  if (_status == Inactive) {
801  DPRINTF(Activity, "[tid:%i] Activating stage.\n",tid);
802 
803  if (fetchStatus[tid] == IcacheAccessComplete) {
804  DPRINTF(Activity, "[tid:%i] Activating fetch due to cache"
805  "completion\n",tid);
806  }
807 
809  }
810 
811  return Active;
812  }
813  }
814 
815  // Stage is switching from active to inactive, notify CPU of it.
816  if (_status == Active) {
817  DPRINTF(Activity, "Deactivating stage.\n");
818 
820  }
821 
822  return Inactive;
823 }
824 
825 void
826 Fetch::squash(const PCStateBase &new_pc, const InstSeqNum seq_num,
827  DynInstPtr squashInst, ThreadID tid)
828 {
829  DPRINTF(Fetch, "[tid:%i] Squash from commit.\n", tid);
830 
831  doSquash(new_pc, squashInst, tid);
832 
833  // Tell the CPU to remove any instructions that are not in the ROB.
834  cpu->removeInstsNotInROB(tid);
835 }
836 
837 void
839 {
840  std::list<ThreadID>::iterator threads = activeThreads->begin();
842  bool status_change = false;
843 
844  wroteToTimeBuffer = false;
845 
846  for (ThreadID i = 0; i < numThreads; ++i) {
847  issuePipelinedIfetch[i] = false;
848  }
849 
850  while (threads != end) {
851  ThreadID tid = *threads++;
852 
853  // Check the signals for each thread to determine the proper status
854  // for each thread.
855  bool updated_status = checkSignalsAndUpdate(tid);
856  status_change = status_change || updated_status;
857  }
858 
859  DPRINTF(Fetch, "Running stage.\n");
860 
861  if (FullSystem) {
862  if (fromCommit->commitInfo[0].interruptPending) {
863  interruptPending = true;
864  }
865 
866  if (fromCommit->commitInfo[0].clearInterrupt) {
867  interruptPending = false;
868  }
869  }
870 
872  threadFetched++) {
873  // Fetch each of the actively fetching threads.
874  fetch(status_change);
875  }
876 
877  // Record number of instructions fetched this cycle for distribution.
879 
880  if (status_change) {
881  // Change the fetch stage status if there was a status change.
883  }
884 
885  // Issue the next I-cache request if possible.
886  for (ThreadID i = 0; i < numThreads; ++i) {
887  if (issuePipelinedIfetch[i]) {
889  }
890  }
891 
892  // Send instructions enqueued into the fetch queue to decode.
893  // Limit rate by fetchWidth. Stall if decode is stalled.
894  unsigned insts_to_decode = 0;
895  unsigned available_insts = 0;
896 
897  for (auto tid : *activeThreads) {
898  if (!stalls[tid].decode) {
899  available_insts += fetchQueue[tid].size();
900  }
901  }
902 
903  // Pick a random thread to start trying to grab instructions from
904  auto tid_itr = activeThreads->begin();
905  std::advance(tid_itr,
906  random_mt.random<uint8_t>(0, activeThreads->size() - 1));
907 
908  while (available_insts != 0 && insts_to_decode < decodeWidth) {
909  ThreadID tid = *tid_itr;
910  if (!stalls[tid].decode && !fetchQueue[tid].empty()) {
911  const auto& inst = fetchQueue[tid].front();
912  toDecode->insts[toDecode->size++] = inst;
913  DPRINTF(Fetch, "[tid:%i] [sn:%llu] Sending instruction to decode "
914  "from fetch queue. Fetch queue size: %i.\n",
915  tid, inst->seqNum, fetchQueue[tid].size());
916 
917  wroteToTimeBuffer = true;
918  fetchQueue[tid].pop_front();
919  insts_to_decode++;
920  available_insts--;
921  }
922 
923  tid_itr++;
924  // Wrap around if at end of active threads list
925  if (tid_itr == activeThreads->end())
926  tid_itr = activeThreads->begin();
927  }
928 
929  // If there was activity this cycle, inform the CPU of it.
930  if (wroteToTimeBuffer) {
931  DPRINTF(Activity, "Activity this cycle.\n");
933  }
934 
935  // Reset the number of the instruction we've fetched.
936  numInst = 0;
937 }
938 
939 bool
941 {
942  // Update the per thread stall statuses.
943  if (fromDecode->decodeBlock[tid]) {
944  stalls[tid].decode = true;
945  }
946 
947  if (fromDecode->decodeUnblock[tid]) {
948  assert(stalls[tid].decode);
949  assert(!fromDecode->decodeBlock[tid]);
950  stalls[tid].decode = false;
951  }
952 
953  // Check squash signals from commit.
954  if (fromCommit->commitInfo[tid].squash) {
955 
956  DPRINTF(Fetch, "[tid:%i] Squashing instructions due to squash "
957  "from commit.\n",tid);
958  // In any case, squash.
959  squash(*fromCommit->commitInfo[tid].pc,
960  fromCommit->commitInfo[tid].doneSeqNum,
961  fromCommit->commitInfo[tid].squashInst, tid);
962 
963  // If it was a branch mispredict on a control instruction, update the
964  // branch predictor with that instruction, otherwise just kill the
965  // invalid state we generated in after sequence number
966  if (fromCommit->commitInfo[tid].mispredictInst &&
967  fromCommit->commitInfo[tid].mispredictInst->isControl()) {
968  branchPred->squash(fromCommit->commitInfo[tid].doneSeqNum,
969  *fromCommit->commitInfo[tid].pc,
970  fromCommit->commitInfo[tid].branchTaken, tid);
971  } else {
972  branchPred->squash(fromCommit->commitInfo[tid].doneSeqNum,
973  tid);
974  }
975 
976  return true;
977  } else if (fromCommit->commitInfo[tid].doneSeqNum) {
978  // Update the branch predictor if it wasn't a squashed instruction
979  // that was broadcasted.
980  branchPred->update(fromCommit->commitInfo[tid].doneSeqNum, tid);
981  }
982 
983  // Check squash signals from decode.
984  if (fromDecode->decodeInfo[tid].squash) {
985  DPRINTF(Fetch, "[tid:%i] Squashing instructions due to squash "
986  "from decode.\n",tid);
987 
988  // Update the branch predictor.
989  if (fromDecode->decodeInfo[tid].branchMispredict) {
990  branchPred->squash(fromDecode->decodeInfo[tid].doneSeqNum,
991  *fromDecode->decodeInfo[tid].nextPC,
992  fromDecode->decodeInfo[tid].branchTaken, tid);
993  } else {
994  branchPred->squash(fromDecode->decodeInfo[tid].doneSeqNum,
995  tid);
996  }
997 
998  if (fetchStatus[tid] != Squashing) {
999 
1000  DPRINTF(Fetch, "Squashing from decode with PC = %s\n",
1001  *fromDecode->decodeInfo[tid].nextPC);
1002  // Squash unless we're already squashing
1003  squashFromDecode(*fromDecode->decodeInfo[tid].nextPC,
1004  fromDecode->decodeInfo[tid].squashInst,
1005  fromDecode->decodeInfo[tid].doneSeqNum,
1006  tid);
1007 
1008  return true;
1009  }
1010  }
1011 
1012  if (checkStall(tid) &&
1013  fetchStatus[tid] != IcacheWaitResponse &&
1014  fetchStatus[tid] != IcacheWaitRetry &&
1015  fetchStatus[tid] != ItlbWait &&
1016  fetchStatus[tid] != QuiescePending) {
1017  DPRINTF(Fetch, "[tid:%i] Setting to blocked\n",tid);
1018 
1019  fetchStatus[tid] = Blocked;
1020 
1021  return true;
1022  }
1023 
1024  if (fetchStatus[tid] == Blocked ||
1025  fetchStatus[tid] == Squashing) {
1026  // Switch status to running if fetch isn't being told to block or
1027  // squash this cycle.
1028  DPRINTF(Fetch, "[tid:%i] Done squashing, switching to running.\n",
1029  tid);
1030 
1031  fetchStatus[tid] = Running;
1032 
1033  return true;
1034  }
1035 
1036  // If we've reached this point, we have not gotten any signals that
1037  // cause fetch to change its status. Fetch remains the same as before.
1038  return false;
1039 }
1040 
1041 DynInstPtr
1043  StaticInstPtr curMacroop, const PCStateBase &this_pc,
1044  const PCStateBase &next_pc, bool trace)
1045 {
1046  // Get a sequence number.
1048 
1049  DynInst::Arrays arrays;
1050  arrays.numSrcs = staticInst->numSrcRegs();
1051  arrays.numDests = staticInst->numDestRegs();
1052 
1053  // Create a new DynInst from the instruction fetched.
1054  DynInstPtr instruction = new (arrays) DynInst(
1055  arrays, staticInst, curMacroop, this_pc, next_pc, seq, cpu);
1056  instruction->setTid(tid);
1057 
1058  instruction->setThreadState(cpu->thread[tid]);
1059 
1060  DPRINTF(Fetch, "[tid:%i] Instruction PC %s created [sn:%lli].\n",
1061  tid, this_pc, seq);
1062 
1063  DPRINTF(Fetch, "[tid:%i] Instruction is: %s\n", tid,
1064  instruction->staticInst->disassemble(this_pc.instAddr()));
1065 
1066 #if TRACING_ON
1067  if (trace) {
1068  instruction->traceData =
1070  instruction->staticInst, this_pc, curMacroop);
1071  }
1072 #else
1073  instruction->traceData = NULL;
1074 #endif
1075 
1076  // Add instruction to the CPU's list of instructions.
1077  instruction->setInstListIt(cpu->addInst(instruction));
1078 
1079  // Write the instruction to the first slot in the queue
1080  // that heads to decode.
1081  assert(numInst < fetchWidth);
1082  fetchQueue[tid].push_back(instruction);
1083  assert(fetchQueue[tid].size() <= fetchQueueSize);
1084  DPRINTF(Fetch, "[tid:%i] Fetch queue entry created (%i/%i).\n",
1085  tid, fetchQueue[tid].size(), fetchQueueSize);
1086  //toDecode->insts[toDecode->size++] = instruction;
1087 
1088  // Keep track of if we can take an interrupt at this boundary
1089  delayedCommit[tid] = instruction->isDelayedCommit();
1090 
1091  return instruction;
1092 }
1093 
1094 void
1095 Fetch::fetch(bool &status_change)
1096 {
1098  // Start actual fetch
1100  ThreadID tid = getFetchingThread();
1101 
1102  assert(!cpu->switchedOut());
1103 
1104  if (tid == InvalidThreadID) {
1105  // Breaks looping condition in tick()
1107 
1108  if (numThreads == 1) { // @todo Per-thread stats
1109  profileStall(0);
1110  }
1111 
1112  return;
1113  }
1114 
1115  DPRINTF(Fetch, "Attempting to fetch from [tid:%i]\n", tid);
1116 
1117  // The current PC.
1118  PCStateBase &this_pc = *pc[tid];
1119 
1120  Addr pcOffset = fetchOffset[tid];
1121  Addr fetchAddr = (this_pc.instAddr() + pcOffset) & decoder[tid]->pcMask();
1122 
1123  bool inRom = isRomMicroPC(this_pc.microPC());
1124 
1125  // If returning from the delay of a cache miss, then update the status
1126  // to running, otherwise do the cache access. Possibly move this up
1127  // to tick() function.
1128  if (fetchStatus[tid] == IcacheAccessComplete) {
1129  DPRINTF(Fetch, "[tid:%i] Icache miss is complete.\n", tid);
1130 
1131  fetchStatus[tid] = Running;
1132  status_change = true;
1133  } else if (fetchStatus[tid] == Running) {
1134  // Align the fetch PC so its at the start of a fetch buffer segment.
1135  Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1136 
1137  // If buffer is no longer valid or fetchAddr has moved to point
1138  // to the next cache block, AND we have no remaining ucode
1139  // from a macro-op, then start fetch from icache.
1140  if (!(fetchBufferValid[tid] &&
1141  fetchBufferBlockPC == fetchBufferPC[tid]) && !inRom &&
1142  !macroop[tid]) {
1143  DPRINTF(Fetch, "[tid:%i] Attempting to translate and read "
1144  "instruction, starting at PC %s.\n", tid, this_pc);
1145 
1146  fetchCacheLine(fetchAddr, tid, this_pc.instAddr());
1147 
1148  if (fetchStatus[tid] == IcacheWaitResponse)
1150  else if (fetchStatus[tid] == ItlbWait)
1152  else
1154  return;
1155  } else if (checkInterrupt(this_pc.instAddr()) &&
1156  !delayedCommit[tid]) {
1157  // Stall CPU if an interrupt is posted and we're not issuing
1158  // an delayed commit micro-op currently (delayed commit
1159  // instructions are not interruptable by interrupts, only faults)
1161  DPRINTF(Fetch, "[tid:%i] Fetch is stalled!\n", tid);
1162  return;
1163  }
1164  } else {
1165  if (fetchStatus[tid] == Idle) {
1167  DPRINTF(Fetch, "[tid:%i] Fetch is idle!\n", tid);
1168  }
1169 
1170  // Status is Idle, so fetch should do nothing.
1171  return;
1172  }
1173 
1174  ++fetchStats.cycles;
1175 
1176  std::unique_ptr<PCStateBase> next_pc(this_pc.clone());
1177 
1178  StaticInstPtr staticInst = NULL;
1179  StaticInstPtr curMacroop = macroop[tid];
1180 
1181  // If the read of the first instruction was successful, then grab the
1182  // instructions from the rest of the cache line and put them into the
1183  // queue heading to decode.
1184 
1185  DPRINTF(Fetch, "[tid:%i] Adding instructions to queue to "
1186  "decode.\n", tid);
1187 
1188  // Need to keep track of whether or not a predicted branch
1189  // ended this fetch block.
1190  bool predictedBranch = false;
1191 
1192  // Need to halt fetch if quiesce instruction detected
1193  bool quiesce = false;
1194 
1195  const unsigned numInsts = fetchBufferSize / instSize;
1196  unsigned blkOffset = (fetchAddr - fetchBufferPC[tid]) / instSize;
1197 
1198  auto *dec_ptr = decoder[tid];
1199  const Addr pc_mask = dec_ptr->pcMask();
1200 
1201  // Loop through instruction memory from the cache.
1202  // Keep issuing while fetchWidth is available and branch is not
1203  // predicted taken
1204  while (numInst < fetchWidth && fetchQueue[tid].size() < fetchQueueSize
1205  && !predictedBranch && !quiesce) {
1206  // We need to process more memory if we aren't going to get a
1207  // StaticInst from the rom, the current macroop, or what's already
1208  // in the decoder.
1209  bool needMem = !inRom && !curMacroop && !dec_ptr->instReady();
1210  fetchAddr = (this_pc.instAddr() + pcOffset) & pc_mask;
1211  Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1212 
1213  if (needMem) {
1214  // If buffer is no longer valid or fetchAddr has moved to point
1215  // to the next cache block then start fetch from icache.
1216  if (!fetchBufferValid[tid] ||
1217  fetchBufferBlockPC != fetchBufferPC[tid])
1218  break;
1219 
1220  if (blkOffset >= numInsts) {
1221  // We need to process more memory, but we've run out of the
1222  // current block.
1223  break;
1224  }
1225 
1226  memcpy(dec_ptr->moreBytesPtr(),
1227  fetchBuffer[tid] + blkOffset * instSize, instSize);
1228  decoder[tid]->moreBytes(this_pc, fetchAddr);
1229 
1230  if (dec_ptr->needMoreBytes()) {
1231  blkOffset++;
1232  fetchAddr += instSize;
1233  pcOffset += instSize;
1234  }
1235  }
1236 
1237  // Extract as many instructions and/or microops as we can from
1238  // the memory we've processed so far.
1239  do {
1240  if (!(curMacroop || inRom)) {
1241  if (dec_ptr->instReady()) {
1242  staticInst = dec_ptr->decode(this_pc);
1243 
1244  // Increment stat of fetched instructions.
1245  ++fetchStats.insts;
1246 
1247  if (staticInst->isMacroop()) {
1248  curMacroop = staticInst;
1249  } else {
1250  pcOffset = 0;
1251  }
1252  } else {
1253  // We need more bytes for this instruction so blkOffset and
1254  // pcOffset will be updated
1255  break;
1256  }
1257  }
1258  // Whether we're moving to a new macroop because we're at the
1259  // end of the current one, or the branch predictor incorrectly
1260  // thinks we are...
1261  bool newMacro = false;
1262  if (curMacroop || inRom) {
1263  if (inRom) {
1264  staticInst = dec_ptr->fetchRomMicroop(
1265  this_pc.microPC(), curMacroop);
1266  } else {
1267  staticInst = curMacroop->fetchMicroop(this_pc.microPC());
1268  }
1269  newMacro |= staticInst->isLastMicroop();
1270  }
1271 
1272  DynInstPtr instruction = buildInst(
1273  tid, staticInst, curMacroop, this_pc, *next_pc, true);
1274 
1275  ppFetch->notify(instruction);
1276  numInst++;
1277 
1278 #if TRACING_ON
1279  if (debug::O3PipeView) {
1280  instruction->fetchTick = curTick();
1281  }
1282 #endif
1283 
1284  set(next_pc, this_pc);
1285 
1286  // If we're branching after this instruction, quit fetching
1287  // from the same block.
1288  predictedBranch |= this_pc.branching();
1289  predictedBranch |= lookupAndUpdateNextPC(instruction, *next_pc);
1290  if (predictedBranch) {
1291  DPRINTF(Fetch, "Branch detected with PC = %s\n", this_pc);
1292  }
1293 
1294  newMacro |= this_pc.instAddr() != next_pc->instAddr();
1295 
1296  // Move to the next instruction, unless we have a branch.
1297  set(this_pc, *next_pc);
1298  inRom = isRomMicroPC(this_pc.microPC());
1299 
1300  if (newMacro) {
1301  fetchAddr = this_pc.instAddr() & pc_mask;
1302  blkOffset = (fetchAddr - fetchBufferPC[tid]) / instSize;
1303  pcOffset = 0;
1304  curMacroop = NULL;
1305  }
1306 
1307  if (instruction->isQuiesce()) {
1308  DPRINTF(Fetch,
1309  "Quiesce instruction encountered, halting fetch!\n");
1310  fetchStatus[tid] = QuiescePending;
1311  status_change = true;
1312  quiesce = true;
1313  break;
1314  }
1315  } while ((curMacroop || dec_ptr->instReady()) &&
1316  numInst < fetchWidth &&
1317  fetchQueue[tid].size() < fetchQueueSize);
1318 
1319  // Re-evaluate whether the next instruction to fetch is in micro-op ROM
1320  // or not.
1321  inRom = isRomMicroPC(this_pc.microPC());
1322  }
1323 
1324  if (predictedBranch) {
1325  DPRINTF(Fetch, "[tid:%i] Done fetching, predicted branch "
1326  "instruction encountered.\n", tid);
1327  } else if (numInst >= fetchWidth) {
1328  DPRINTF(Fetch, "[tid:%i] Done fetching, reached fetch bandwidth "
1329  "for this cycle.\n", tid);
1330  } else if (blkOffset >= fetchBufferSize) {
1331  DPRINTF(Fetch, "[tid:%i] Done fetching, reached the end of the"
1332  "fetch buffer.\n", tid);
1333  }
1334 
1335  macroop[tid] = curMacroop;
1336  fetchOffset[tid] = pcOffset;
1337 
1338  if (numInst > 0) {
1339  wroteToTimeBuffer = true;
1340  }
1341 
1342  // pipeline a fetch if we're crossing a fetch buffer boundary and not in
1343  // a state that would preclude fetching
1344  fetchAddr = (this_pc.instAddr() + pcOffset) & pc_mask;
1345  Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1346  issuePipelinedIfetch[tid] = fetchBufferBlockPC != fetchBufferPC[tid] &&
1347  fetchStatus[tid] != IcacheWaitResponse &&
1348  fetchStatus[tid] != ItlbWait &&
1349  fetchStatus[tid] != IcacheWaitRetry &&
1350  fetchStatus[tid] != QuiescePending &&
1351  !curMacroop;
1352 }
1353 
1354 void
1356 {
1357  if (retryPkt != NULL) {
1358  assert(cacheBlocked);
1359  assert(retryTid != InvalidThreadID);
1360  assert(fetchStatus[retryTid] == IcacheWaitRetry);
1361 
1364  // Notify Fetch Request probe when a retryPkt is successfully sent.
1365  // Note that notify must be called before retryPkt is set to NULL.
1367  retryPkt = NULL;
1369  cacheBlocked = false;
1370  }
1371  } else {
1372  assert(retryTid == InvalidThreadID);
1373  // Access has been squashed since it was sent out. Just clear
1374  // the cache being blocked.
1375  cacheBlocked = false;
1376  }
1377 }
1378 
1380 // //
1381 // SMT FETCH POLICY MAINTAINED HERE //
1382 // //
1384 ThreadID
1386 {
1387  if (numThreads > 1) {
1388  switch (fetchPolicy) {
1389  case SMTFetchPolicy::RoundRobin:
1390  return roundRobin();
1391  case SMTFetchPolicy::IQCount:
1392  return iqCount();
1393  case SMTFetchPolicy::LSQCount:
1394  return lsqCount();
1395  case SMTFetchPolicy::Branch:
1396  return branchCount();
1397  default:
1398  return InvalidThreadID;
1399  }
1400  } else {
1401  std::list<ThreadID>::iterator thread = activeThreads->begin();
1402  if (thread == activeThreads->end()) {
1403  return InvalidThreadID;
1404  }
1405 
1406  ThreadID tid = *thread;
1407 
1408  if (fetchStatus[tid] == Running ||
1410  fetchStatus[tid] == Idle) {
1411  return tid;
1412  } else {
1413  return InvalidThreadID;
1414  }
1415  }
1416 }
1417 
1418 
1419 ThreadID
1421 {
1422  std::list<ThreadID>::iterator pri_iter = priorityList.begin();
1424 
1425  ThreadID high_pri;
1426 
1427  while (pri_iter != end) {
1428  high_pri = *pri_iter;
1429 
1430  assert(high_pri <= numThreads);
1431 
1432  if (fetchStatus[high_pri] == Running ||
1433  fetchStatus[high_pri] == IcacheAccessComplete ||
1434  fetchStatus[high_pri] == Idle) {
1435 
1436  priorityList.erase(pri_iter);
1437  priorityList.push_back(high_pri);
1438 
1439  return high_pri;
1440  }
1441 
1442  pri_iter++;
1443  }
1444 
1445  return InvalidThreadID;
1446 }
1447 
1448 ThreadID
1450 {
1451  //sorted from lowest->highest
1452  std::priority_queue<unsigned, std::vector<unsigned>,
1453  std::greater<unsigned> > PQ;
1454  std::map<unsigned, ThreadID> threadMap;
1455 
1456  std::list<ThreadID>::iterator threads = activeThreads->begin();
1458 
1459  while (threads != end) {
1460  ThreadID tid = *threads++;
1461  unsigned iqCount = fromIEW->iewInfo[tid].iqCount;
1462 
1463  //we can potentially get tid collisions if two threads
1464  //have the same iqCount, but this should be rare.
1465  PQ.push(iqCount);
1466  threadMap[iqCount] = tid;
1467  }
1468 
1469  while (!PQ.empty()) {
1470  ThreadID high_pri = threadMap[PQ.top()];
1471 
1472  if (fetchStatus[high_pri] == Running ||
1473  fetchStatus[high_pri] == IcacheAccessComplete ||
1474  fetchStatus[high_pri] == Idle)
1475  return high_pri;
1476  else
1477  PQ.pop();
1478 
1479  }
1480 
1481  return InvalidThreadID;
1482 }
1483 
1484 ThreadID
1486 {
1487  //sorted from lowest->highest
1488  std::priority_queue<unsigned, std::vector<unsigned>,
1489  std::greater<unsigned> > PQ;
1490  std::map<unsigned, ThreadID> threadMap;
1491 
1492  std::list<ThreadID>::iterator threads = activeThreads->begin();
1494 
1495  while (threads != end) {
1496  ThreadID tid = *threads++;
1497  unsigned ldstqCount = fromIEW->iewInfo[tid].ldstqCount;
1498 
1499  //we can potentially get tid collisions if two threads
1500  //have the same iqCount, but this should be rare.
1501  PQ.push(ldstqCount);
1502  threadMap[ldstqCount] = tid;
1503  }
1504 
1505  while (!PQ.empty()) {
1506  ThreadID high_pri = threadMap[PQ.top()];
1507 
1508  if (fetchStatus[high_pri] == Running ||
1509  fetchStatus[high_pri] == IcacheAccessComplete ||
1510  fetchStatus[high_pri] == Idle)
1511  return high_pri;
1512  else
1513  PQ.pop();
1514  }
1515 
1516  return InvalidThreadID;
1517 }
1518 
1519 ThreadID
1521 {
1522  panic("Branch Count Fetch policy unimplemented\n");
1523  return InvalidThreadID;
1524 }
1525 
1526 void
1528 {
1529  if (!issuePipelinedIfetch[tid]) {
1530  return;
1531  }
1532 
1533  // The next PC to access.
1534  const PCStateBase &this_pc = *pc[tid];
1535 
1536  if (isRomMicroPC(this_pc.microPC())) {
1537  return;
1538  }
1539 
1540  Addr pcOffset = fetchOffset[tid];
1541  Addr fetchAddr = (this_pc.instAddr() + pcOffset) & decoder[tid]->pcMask();
1542 
1543  // Align the fetch PC so its at the start of a fetch buffer segment.
1544  Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1545 
1546  // Unless buffer already got the block, fetch it from icache.
1547  if (!(fetchBufferValid[tid] && fetchBufferBlockPC == fetchBufferPC[tid])) {
1548  DPRINTF(Fetch, "[tid:%i] Issuing a pipelined I-cache access, "
1549  "starting at PC %s.\n", tid, this_pc);
1550 
1551  fetchCacheLine(fetchAddr, tid, this_pc.instAddr());
1552  }
1553 }
1554 
1555 void
1557 {
1558  DPRINTF(Fetch,"There are no more threads available to fetch from.\n");
1559 
1560  // @todo Per-thread stats
1561 
1562  if (stalls[tid].drain) {
1564  DPRINTF(Fetch, "Fetch is waiting for a drain!\n");
1565  } else if (activeThreads->empty()) {
1567  DPRINTF(Fetch, "Fetch has no active thread!\n");
1568  } else if (fetchStatus[tid] == Blocked) {
1570  DPRINTF(Fetch, "[tid:%i] Fetch is blocked!\n", tid);
1571  } else if (fetchStatus[tid] == Squashing) {
1573  DPRINTF(Fetch, "[tid:%i] Fetch is squashing!\n", tid);
1574  } else if (fetchStatus[tid] == IcacheWaitResponse) {
1576  DPRINTF(Fetch, "[tid:%i] Fetch is waiting cache response!\n",
1577  tid);
1578  } else if (fetchStatus[tid] == ItlbWait) {
1580  DPRINTF(Fetch, "[tid:%i] Fetch is waiting ITLB walk to "
1581  "finish!\n", tid);
1582  } else if (fetchStatus[tid] == TrapPending) {
1584  DPRINTF(Fetch, "[tid:%i] Fetch is waiting for a pending trap!\n",
1585  tid);
1586  } else if (fetchStatus[tid] == QuiescePending) {
1588  DPRINTF(Fetch, "[tid:%i] Fetch is waiting for a pending quiesce "
1589  "instruction!\n", tid);
1590  } else if (fetchStatus[tid] == IcacheWaitRetry) {
1592  DPRINTF(Fetch, "[tid:%i] Fetch is waiting for an I-cache retry!\n",
1593  tid);
1594  } else if (fetchStatus[tid] == NoGoodAddr) {
1595  DPRINTF(Fetch, "[tid:%i] Fetch predicted non-executable address\n",
1596  tid);
1597  } else {
1598  DPRINTF(Fetch, "[tid:%i] Unexpected fetch stall reason "
1599  "(Status: %i)\n",
1600  tid, fetchStatus[tid]);
1601  }
1602 }
1603 
1604 bool
1606 {
1607  DPRINTF(O3CPU, "Fetch unit received timing\n");
1608  // We shouldn't ever get a cacheable block in Modified state
1609  assert(pkt->req->isUncacheable() ||
1610  !(pkt->cacheResponding() && !pkt->hasSharers()));
1611  fetch->processCacheCompletion(pkt);
1612 
1613  return true;
1614 }
1615 
1616 void
1618 {
1619  fetch->recvReqRetry();
1620 }
1621 
1622 } // namespace o3
1623 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
RequestorID instRequestorId() const
Reads this CPU's unique instruction requestor ID.
Definition: base.hh:191
uint32_t taskId() const
Get cpu task id.
Definition: base.hh:207
ThreadID contextToThread(ContextID cid)
Convert ContextID to threadID.
Definition: base.hh:295
bool switchedOut() const
Determine if the CPU is switched out.
Definition: base.hh:356
trace::InstTracer * getTracer()
Provide access to the tracer pointer.
Definition: base.hh:268
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)
Definition: mmu.cc:111
@ Execute
Definition: mmu.hh:56
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:79
size_t moreBytesSize() const
Definition: decoder.hh:96
virtual void reset()
Definition: decoder.hh:63
virtual void moreBytes(const PCStateBase &pc, Addr fetchPC)=0
Feed data to the decoder.
Addr pcMask() const
Definition: decoder.hh:97
virtual std::string name() const
Definition: named.hh:47
virtual bool branching() const =0
MicroPC microPC() const
Returns the current micropc.
Definition: pcstate.hh:118
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition: pcstate.hh:107
virtual PCStateBase * clone() const =0
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
Definition: packet.hh:1200
const T * getConstPtr() const
Definition: packet.hh:1221
bool cacheResponding() const
Definition: packet.hh:657
bool hasSharers() const
Definition: packet.hh:684
bool isConnected() const
Is this port currently connected to a peer?
Definition: port.hh:133
ProbePointArg generates a point for the class of Arg.
Definition: probe.hh:264
void notify(const Arg &arg)
called at the ProbePoint call site, passes arg to each listener.
Definition: probe.hh:313
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Definition: port.hh:79
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition: port.hh:495
@ INST_FETCH
The request was an instruction fetch.
Definition: request.hh:115
uint8_t numSrcRegs() const
Number of source registers.
Definition: static_inst.hh:123
virtual StaticInstPtr fetchMicroop(MicroPC upc) const
Return the microop that goes with a particular micropc.
Definition: static_inst.cc:39
uint8_t numDestRegs() const
Number of destination registers.
Definition: static_inst.hh:125
bool isMacroop() const
Definition: static_inst.hh:185
bool isLastMicroop() const
Definition: static_inst.hh:188
bool isMemAddr(Addr addr) const
Check if a physical address is within a range of a memory that is part of the global address map.
Definition: system.cc:288
wire getWire(int idx)
Definition: timebuf.hh:232
void update(const InstSeqNum &done_sn, ThreadID tid)
Tells the branch predictor to commit any updates until the given sequence number.
Definition: bpred_unit.cc:310
bool predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, PCStateBase &pc, ThreadID tid)
Predicts whether or not the instruction is a taken branch, and the target of the branch if it is take...
Definition: bpred_unit.cc:132
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: bpred_unit.cc:123
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
Definition: bpred_unit.cc:333
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition: cpu.hh:94
ListIt addInst(const DynInstPtr &inst)
Function to add instruction onto the head of the list of the instructions.
Definition: cpu.cc:1216
ProbePointArg< PacketPtr > * ppInstAccessComplete
Definition: cpu.hh:173
std::vector< ThreadState * > thread
Pointers to all of the threads in the CPU.
Definition: cpu.hh:530
Port & getInstPort() override
Used by the fetch unit to get a hold of the instruction port.
Definition: cpu.hh:561
void activityThisCycle()
Records that there was time buffer activity this cycle.
Definition: cpu.hh:485
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
Definition: cpu.cc:1300
bool isDraining() const
Is the CPU draining?
Definition: cpu.hh:235
void removeInstsNotInROB(ThreadID tid)
Remove all instructions that are not currently in the ROB.
Definition: cpu.cc:1256
@ FetchIdx
Definition: cpu.hh:453
void deactivateStage(const StageIdx idx)
Changes a stage's status to inactive within the activity recorder.
Definition: cpu.hh:496
BaseMMU * mmu
Definition: cpu.hh:110
System * system
Pointer to the system.
Definition: cpu.hh:527
gem5::ThreadContext * tcBase(ThreadID tid)
Returns a pointer to a thread context.
Definition: cpu.hh:512
InstSeqNum getAndIncrementInstSeq()
Get the current instruction sequence number, and increment it.
Definition: cpu.hh:281
void pcState(const PCStateBase &new_pc_state, ThreadID tid)
Sets the commit PC state of a specific thread.
Definition: cpu.cc:1203
void activateStage(const StageIdx idx)
Changes a stage's status to active within the activity recorder.
Definition: cpu.hh:489
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
Definition: cpu.cc:1399
void setReq(const RequestPtr &_req)
Definition: fetch.hh:141
virtual bool recvTimingResp(PacketPtr pkt)
Timing version of receive.
Definition: fetch.cc:1605
IcachePort(Fetch *_fetch, CPU *_cpu)
Default constructor.
Definition: fetch.cc:78
virtual void recvReqRetry()
Handles doing a retry of a failed fetch.
Definition: fetch.cc:1617
Fetch class handles both single threaded and SMT fetch.
Definition: fetch.hh:79
gem5::o3::Fetch::FetchStatGroup fetchStats
bool wroteToTimeBuffer
Variable that tracks if fetch has written to the time buffer this cycle.
Definition: fetch.hh:430
void deactivateThread(ThreadID tid)
For priority-based fetch policies, need to keep update priorityList.
Definition: fetch.cc:499
FetchStatus
Overall fetch status.
Definition: fetch.hh:163
std::list< ThreadID > * activeThreads
List of Active Threads.
Definition: fetch.hh:505
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's information from backwards time buffer.
Definition: fetch.hh:406
Cycles renameToFetchDelay
Rename to fetch delay.
Definition: fetch.hh:449
StaticInstPtr macroop[MaxThreads]
Definition: fetch.hh:419
void fetch(bool &status_change)
Does the actual fetching of instructions and passing them on to the next stage.
Definition: fetch.cc:1095
void takeOverFrom()
Takes over from another CPU's thread.
Definition: fetch.cc:449
unsigned int cacheBlkSize
Cache block size.
Definition: fetch.hh:473
uint8_t * fetchBuffer[MaxThreads]
The fetch data that is being fetched and buffered.
Definition: fetch.hh:484
void doSquash(const PCStateBase &new_pc, const DynInstPtr squashInst, ThreadID tid)
Squashes a specific thread and resets the PC.
Definition: fetch.cc:709
TimeBuffer< FetchStruct >::wire toDecode
Wire used to write any information heading to decode.
Definition: fetch.hh:410
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: fetch.cc:273
bool lookupAndUpdateNextPC(const DynInstPtr &inst, PCStateBase &pc)
Looks up in the branch predictor to see if the next PC should be either next PC+=MachInst or a branch...
Definition: fetch.cc:509
ThreadStatus fetchStatus[MaxThreads]
Per-thread status.
Definition: fetch.hh:190
ThreadID numThreads
Number of threads.
Definition: fetch.hh:508
TimeBuffer< TimeStruct >::wire fromDecode
Wire to get decode's information from backwards time buffer.
Definition: fetch.hh:397
ProbePointArg< DynInstPtr > * ppFetch
Probe points.
Definition: fetch.hh:199
TimeBuffer< TimeStruct >::wire fromRename
Wire to get rename's information from backwards time buffer.
Definition: fetch.hh:400
void squash(const PCStateBase &new_pc, const InstSeqNum seq_num, DynInstPtr squashInst, ThreadID tid)
Squashes a specific thread and resets the PC.
Definition: fetch.cc:826
void squashFromDecode(const PCStateBase &new_pc, const DynInstPtr squashInst, const InstSeqNum seq_num, ThreadID tid)
Squashes a specific thread and resets the PC.
Definition: fetch.cc:760
FetchStatus updateFetchStatus()
Updates overall fetch stage status; to be called at the end of each cycle.
Definition: fetch.cc:787
ThreadID getFetchingThread()
Returns the appropriate thread to fetch, given the fetch policy.
Definition: fetch.cc:1385
bool fetchBufferValid[MaxThreads]
Whether or not the fetch buffer data is valid.
Definition: fetch.hh:496
void startupStage()
Initialize stage.
Definition: fetch.cc:286
void pipelineIcacheAccesses(ThreadID tid)
Pipeline the next I-cache access to the current one.
Definition: fetch.cc:1527
std::string name() const
Returns the name of fetch.
Definition: fetch.cc:148
void wakeFromQuiesce()
Tells fetch to wake up from a quiesce instruction.
Definition: fetch.cc:466
void switchToActive()
Changes the status of this stage to active, and indicates this to the CPU.
Definition: fetch.cc:475
void switchToInactive()
Changes the status of this stage to inactive, and indicates this to the CPU.
Definition: fetch.cc:487
int numInst
Tracks how many instructions has been fetched this cycle.
Definition: fetch.hh:433
bool fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc)
Fetches the cache line that contains the fetch PC.
Definition: fetch.cc:553
Cycles decodeToFetchDelay
Decode to fetch delay.
Definition: fetch.hh:446
bool issuePipelinedIfetch[MaxThreads]
Set to true if a pipelined I-cache request should be issued.
Definition: fetch.hh:525
Addr fetchBufferAlignPC(Addr addr)
Align a PC to the start of a fetch buffer block.
Definition: fetch.hh:352
FetchStatus _status
Fetch status.
Definition: fetch.hh:187
bool delayedCommit[MaxThreads]
Can the fetch stage redirect from an interrupt on this instruction?
Definition: fetch.hh:422
ThreadID threadFetched
Thread ID being fetched.
Definition: fetch.hh:514
SMTFetchPolicy fetchPolicy
Fetch policy.
Definition: fetch.hh:193
branch_prediction::BPredUnit * branchPred
BPredUnit.
Definition: fetch.hh:413
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: fetch.cc:402
unsigned fetchWidth
The width of fetch in instructions.
Definition: fetch.hh:458
unsigned fetchQueueSize
The size of the fetch queue in micro-ops.
Definition: fetch.hh:490
InstDecoder * decoder[MaxThreads]
The decoder.
Definition: fetch.hh:358
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get iew's information from backwards time buffer.
Definition: fetch.hh:403
void regProbePoints()
Registers probes.
Definition: fetch.cc:151
bool checkSignalsAndUpdate(ThreadID tid)
Checks all input signals and updates the status as necessary.
Definition: fetch.cc:940
bool checkStall(ThreadID tid) const
Checks if a thread is stalled.
Definition: fetch.cc:773
IcachePort icachePort
Instruction port.
Definition: fetch.hh:522
@ IcacheAccessComplete
Definition: fetch.hh:181
@ IcacheWaitResponse
Definition: fetch.hh:179
void setTimeBuffer(TimeBuffer< TimeStruct > *time_buffer)
Sets the main backwards communication time buffer pointer.
Definition: fetch.cc:261
void processCacheCompletion(PacketPtr pkt)
Processes cache completion event.
Definition: fetch.cc:350
ThreadID iqCount()
Returns the appropriate thread to fetch using the IQ count policy.
Definition: fetch.cc:1449
Addr fetchBufferMask
Mask to align a fetch address to a fetch buffer boundary.
Definition: fetch.hh:481
void recvReqRetry()
Handles retrying the fetch access.
Definition: fetch.cc:1355
bool checkInterrupt(Addr pc)
Check if an interrupt is pending and that we need to handle.
Definition: fetch.hh:305
Cycles iewToFetchDelay
IEW to fetch delay.
Definition: fetch.hh:452
void resetStage()
Reset this pipeline stage.
Definition: fetch.cc:316
Fetch(CPU *_cpu, const BaseO3CPUParams &params)
Fetch constructor.
Definition: fetch.cc:83
void drainStall(ThreadID tid)
Stall the fetch stage after reaching a safe drain point.
Definition: fetch.cc:457
Counter lastIcacheStall[MaxThreads]
Icache stall statistics.
Definition: fetch.hh:502
int instSize
Size of instructions.
Definition: fetch.hh:499
ProbePointArg< RequestPtr > * ppFetchRequestSent
To probe when a fetch request is successfully sent.
Definition: fetch.hh:201
Cycles commitToFetchDelay
Commit to fetch delay.
Definition: fetch.hh:455
RequestPtr memReq[MaxThreads]
Memory request used to access cache.
Definition: fetch.hh:425
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
Definition: fetch.hh:394
void profileStall(ThreadID tid)
Profile the reasons of fetch stall.
Definition: fetch.cc:1556
ThreadID roundRobin()
Returns the appropriate thread to fetch using a round robin policy.
Definition: fetch.cc:1420
Addr fetchBufferPC[MaxThreads]
The PC of the first instruction loaded into the fetch buffer.
Definition: fetch.hh:487
void drainResume()
Resume after a drain.
Definition: fetch.cc:393
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: fetch.cc:297
void finishTranslation(const Fault &fault, const RequestPtr &mem_req)
Definition: fetch.cc:602
bool interruptPending
Checks if there is an interrupt pending.
Definition: fetch.hh:519
std::unique_ptr< PCStateBase > pc[MaxThreads]
Definition: fetch.hh:415
ThreadID lsqCount()
Returns the appropriate thread to fetch using the LSQ count policy.
Definition: fetch.cc:1485
Stalls stalls[MaxThreads]
Tracks which stages are telling fetch to stall.
Definition: fetch.hh:443
DynInstPtr buildInst(ThreadID tid, StaticInstPtr staticInst, StaticInstPtr curMacroop, const PCStateBase &this_pc, const PCStateBase &next_pc, bool trace)
Definition: fetch.cc:1042
bool isDrained() const
Has the stage drained?
Definition: fetch.cc:419
Addr fetchOffset[MaxThreads]
Definition: fetch.hh:417
std::deque< DynInstPtr > fetchQueue[MaxThreads]
Queue of fetched instructions.
Definition: fetch.hh:493
PacketPtr retryPkt
The packet that is waiting to be retried.
Definition: fetch.hh:467
std::list< ThreadID > priorityList
List that has the threads organized by priority.
Definition: fetch.hh:196
FinishTranslationEvent finishTranslationEvent
Event used to delay fault generation of translation faults.
Definition: fetch.hh:528
ThreadID retryTid
The thread that is waiting on the cache to tell fetch to retry.
Definition: fetch.hh:470
void tick()
Ticks the fetch stage, processing all inputs signals and fetching as many instructions as possible.
Definition: fetch.cc:838
ThreadID numFetchingThreads
Number of threads that are actively fetching.
Definition: fetch.hh:511
unsigned fetchBufferSize
The size of the fetch buffer in bytes.
Definition: fetch.hh:478
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
Definition: fetch.cc:279
CPU * cpu
Pointer to the O3CPU.
Definition: fetch.hh:391
unsigned decodeWidth
The width of decode in instructions.
Definition: fetch.hh:461
bool cacheBlocked
Is the cache blocked? If so no threads can access it.
Definition: fetch.hh:464
ThreadID branchCount()
Returns the appropriate thread to fetch using the branch count policy.
Definition: fetch.cc:1520
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:358
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:372
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1328
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
Definition: statistics.hh:2113
Statistics container.
Definition: group.hh:94
virtual InstRecord * getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst, const PCStateBase &pc, const StaticInstPtr macroStaticInst=nullptr)=0
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
Random random_mt
Definition: random.cc:99
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition: random.hh:90
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:120
#define warn(...)
Definition: logging.hh:246
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 12, 11 > set
Definition: misc_types.hh:709
static constexpr int MaxThreads
Definition: limits.hh:38
static constexpr int MaxWidth
Definition: limits.hh:37
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:109
void quiesce(ThreadContext *tc)
Definition: pseudo_inst.cc:118
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:62
const FlagsType total
Print the total.
Definition: info.hh:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
const ThreadID InvalidThreadID
Definition: types.hh:236
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
static bool isRomMicroPC(MicroPC upc)
Definition: types.hh:166
StaticInstPtr nopStaticInstPtr
Pointer to a statically allocated generic "nop" instruction object.
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
uint64_t InstSeqNum
Definition: inst_seq.hh:40
Declaration of the Packet class.
statistics::Scalar icacheSquashes
Total number of outstanding icache accesses that were dropped due to a squash.
Definition: fetch.hh:575
statistics::Scalar pendingDrainCycles
Total number of cycles spent in waiting for drains.
Definition: fetch.hh:560
statistics::Scalar cacheLines
Stat for total number of fetched cache lines.
Definition: fetch.hh:571
statistics::Formula branchRate
Number of branch fetches per cycle.
Definition: fetch.hh:585
statistics::Scalar blockedCycles
Total number of cycles spent blocked.
Definition: fetch.hh:556
statistics::Scalar idleCycles
Stat for total number of cycles spent blocked due to other stages in the pipeline.
Definition: fetch.hh:554
statistics::Scalar predictedBranches
Stat for total number of predicted branches.
Definition: fetch.hh:543
statistics::Scalar noActiveThreadStallCycles
Total number of stall cycles caused by no active threads to run.
Definition: fetch.hh:562
statistics::Scalar pendingQuiesceStallCycles
Total number of stall cycles caused by pending quiesce instructions.
Definition: fetch.hh:567
statistics::Scalar icacheWaitRetryStallCycles
Total number of stall cycles caused by I-cache wait retrys.
Definition: fetch.hh:569
statistics::Scalar pendingTrapStallCycles
Total number of stall cycles caused by pending traps.
Definition: fetch.hh:564
statistics::Scalar cycles
Stat for total number of cycles spent fetching.
Definition: fetch.hh:545
statistics::Scalar icacheStallCycles
Stat for total number of cycles stalled due to an icache miss.
Definition: fetch.hh:537
statistics::Scalar miscStallCycles
Total number of cycles spent in any other state.
Definition: fetch.hh:558
statistics::Scalar tlbCycles
Stat for total number of cycles spent waiting for translation.
Definition: fetch.hh:549
statistics::Scalar squashCycles
Stat for total number of cycles spent squashing.
Definition: fetch.hh:547
FetchStatGroup(CPU *cpu, Fetch *fetch)
Definition: fetch.cc:159
statistics::Scalar branches
Total number of fetched branches.
Definition: fetch.hh:541
statistics::Formula idleRate
Rate of how often fetch was idle.
Definition: fetch.hh:583
statistics::Scalar insts
Stat for total number of fetched instructions.
Definition: fetch.hh:539
statistics::Formula rate
Number of instruction fetched per cycle.
Definition: fetch.hh:587
statistics::Scalar tlbSquashes
Total number of outstanding tlb accesses that were dropped due to a squash.
Definition: fetch.hh:579
statistics::Distribution nisnDist
Distribution of number of instructions fetched each cycle.
Definition: fetch.hh:581
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:30 for gem5 by doxygen 1.9.1