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

Generated on Tue Sep 21 2021 12:25:04 for gem5 by doxygen 1.8.17