gem5  v22.0.0.1
decode.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2014 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2004-2006 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include "cpu/o3/decode.hh"
42 
43 #include "arch/generic/pcstate.hh"
44 #include "base/trace.hh"
45 #include "config/the_isa.hh"
46 #include "cpu/inst_seq.hh"
47 #include "cpu/o3/dyn_inst.hh"
48 #include "cpu/o3/limits.hh"
49 #include "debug/Activity.hh"
50 #include "debug/Decode.hh"
51 #include "debug/O3PipeView.hh"
52 #include "params/BaseO3CPU.hh"
53 #include "sim/full_system.hh"
54 
55 // clang complains about std::set being overloaded with Packet::set if
56 // we open up the entire namespace std
57 using std::list;
58 
59 namespace gem5
60 {
61 
62 namespace o3
63 {
64 
65 Decode::Decode(CPU *_cpu, const BaseO3CPUParams &params)
66  : cpu(_cpu),
67  renameToDecodeDelay(params.renameToDecodeDelay),
68  iewToDecodeDelay(params.iewToDecodeDelay),
69  commitToDecodeDelay(params.commitToDecodeDelay),
70  fetchToDecodeDelay(params.fetchToDecodeDelay),
71  decodeWidth(params.decodeWidth),
72  numThreads(params.numThreads),
73  stats(_cpu)
74 {
75  if (decodeWidth > MaxWidth)
76  fatal("decodeWidth (%d) is larger than compiled limit (%d),\n"
77  "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
78  decodeWidth, static_cast<int>(MaxWidth));
79 
80  // @todo: Make into a parameter
81  skidBufferMax = (fetchToDecodeDelay + 1) * params.fetchWidth;
82  for (int tid = 0; tid < MaxThreads; tid++) {
83  stalls[tid] = {false};
84  decodeStatus[tid] = Idle;
85  bdelayDoneSeqNum[tid] = 0;
86  squashInst[tid] = nullptr;
87  squashAfterDelaySlot[tid] = 0;
88  }
89 }
90 
91 void
93 {
94  resetStage();
95 }
96 
97 void
99 {
100  decodeStatus[tid] = Idle;
101  stalls[tid].rename = false;
102 }
103 
104 void
106 {
107  _status = Inactive;
108 
109  // Setup status, make sure stall signals are clear.
110  for (ThreadID tid = 0; tid < numThreads; ++tid) {
111  decodeStatus[tid] = Idle;
112 
113  stalls[tid].rename = false;
114  }
115 }
116 
117 std::string
119 {
120  return cpu->name() + ".decode";
121 }
122 
124  : statistics::Group(cpu, "decode"),
125  ADD_STAT(idleCycles, statistics::units::Cycle::get(),
126  "Number of cycles decode is idle"),
127  ADD_STAT(blockedCycles, statistics::units::Cycle::get(),
128  "Number of cycles decode is blocked"),
129  ADD_STAT(runCycles, statistics::units::Cycle::get(),
130  "Number of cycles decode is running"),
131  ADD_STAT(unblockCycles, statistics::units::Cycle::get(),
132  "Number of cycles decode is unblocking"),
133  ADD_STAT(squashCycles, statistics::units::Cycle::get(),
134  "Number of cycles decode is squashing"),
135  ADD_STAT(branchResolved, statistics::units::Count::get(),
136  "Number of times decode resolved a branch"),
137  ADD_STAT(branchMispred, statistics::units::Count::get(),
138  "Number of times decode detected a branch misprediction"),
139  ADD_STAT(controlMispred, statistics::units::Count::get(),
140  "Number of times decode detected an instruction incorrectly "
141  "predicted as a control"),
142  ADD_STAT(decodedInsts, statistics::units::Count::get(),
143  "Number of instructions handled by decode"),
144  ADD_STAT(squashedInsts, statistics::units::Count::get(),
145  "Number of squashed instructions handled by decode")
146 {
157 }
158 
159 void
161 {
162  timeBuffer = tb_ptr;
163 
164  // Setup wire to write information back to fetch.
165  toFetch = timeBuffer->getWire(0);
166 
167  // Create wires to get information from proper places in time buffer.
169  fromIEW = timeBuffer->getWire(-iewToDecodeDelay);
171 }
172 
173 void
175 {
176  decodeQueue = dq_ptr;
177 
178  // Setup wire to write information to proper place in decode queue.
179  toRename = decodeQueue->getWire(0);
180 }
181 
182 void
184 {
185  fetchQueue = fq_ptr;
186 
187  // Setup wire to read information from fetch queue.
189 }
190 
191 void
193 {
194  activeThreads = at_ptr;
195 }
196 
197 void
199 {
200  for (ThreadID tid = 0; tid < numThreads; ++tid) {
201  assert(insts[tid].empty());
202  assert(skidBuffer[tid].empty());
203  }
204 }
205 
206 bool
208 {
209  for (ThreadID tid = 0; tid < numThreads; ++tid) {
210  if (!insts[tid].empty() || !skidBuffer[tid].empty() ||
211  (decodeStatus[tid] != Running && decodeStatus[tid] != Idle))
212  return false;
213  }
214  return true;
215 }
216 
217 bool
219 {
220  bool ret_val = false;
221 
222  if (stalls[tid].rename) {
223  DPRINTF(Decode,"[tid:%i] Stall fom Rename stage detected.\n", tid);
224  ret_val = true;
225  }
226 
227  return ret_val;
228 }
229 
230 bool
232 {
233  return fromFetch->size > 0;
234 }
235 
236 bool
238 {
239  DPRINTF(Decode, "[tid:%i] Blocking.\n", tid);
240 
241  // Add the current inputs to the skid buffer so they can be
242  // reprocessed when this stage unblocks.
243  skidInsert(tid);
244 
245  // If the decode status is blocked or unblocking then decode has not yet
246  // signalled fetch to unblock. In that case, there is no need to tell
247  // fetch to block.
248  if (decodeStatus[tid] != Blocked) {
249  // Set the status to Blocked.
250  decodeStatus[tid] = Blocked;
251 
252  if (toFetch->decodeUnblock[tid]) {
253  toFetch->decodeUnblock[tid] = false;
254  } else {
255  toFetch->decodeBlock[tid] = true;
256  wroteToTimeBuffer = true;
257  }
258 
259  return true;
260  }
261 
262  return false;
263 }
264 
265 bool
267 {
268  // Decode is done unblocking only if the skid buffer is empty.
269  if (skidBuffer[tid].empty()) {
270  DPRINTF(Decode, "[tid:%i] Done unblocking.\n", tid);
271  toFetch->decodeUnblock[tid] = true;
272  wroteToTimeBuffer = true;
273 
274  decodeStatus[tid] = Running;
275  return true;
276  }
277 
278  DPRINTF(Decode, "[tid:%i] Currently unblocking.\n", tid);
279 
280  return false;
281 }
282 
283 void
285 {
286  DPRINTF(Decode, "[tid:%i] [sn:%llu] Squashing due to incorrect branch "
287  "prediction detected at decode.\n", tid, inst->seqNum);
288 
289  // Send back mispredict information.
290  toFetch->decodeInfo[tid].branchMispredict = true;
291  toFetch->decodeInfo[tid].predIncorrect = true;
292  toFetch->decodeInfo[tid].mispredictInst = inst;
293  toFetch->decodeInfo[tid].squash = true;
294  toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
295  set(toFetch->decodeInfo[tid].nextPC, *inst->branchTarget());
296 
297  // Looking at inst->pcState().branching()
298  // may yield unexpected results if the branch
299  // was predicted taken but aliased in the BTB
300  // with a branch jumping to the next instruction (mistarget)
301  // Using PCState::branching() will send execution on the
302  // fallthrough and this will not be caught at execution (since
303  // branch was correctly predicted taken)
304  toFetch->decodeInfo[tid].branchTaken = inst->readPredTaken() |
305  inst->isUncondCtrl();
306 
307  toFetch->decodeInfo[tid].squashInst = inst;
308 
309  InstSeqNum squash_seq_num = inst->seqNum;
310 
311  // Might have to tell fetch to unblock.
312  if (decodeStatus[tid] == Blocked ||
313  decodeStatus[tid] == Unblocking) {
314  toFetch->decodeUnblock[tid] = 1;
315  }
316 
317  // Set status to squashing.
318  decodeStatus[tid] = Squashing;
319 
320  for (int i=0; i<fromFetch->size; i++) {
321  if (fromFetch->insts[i]->threadNumber == tid &&
322  fromFetch->insts[i]->seqNum > squash_seq_num) {
323  fromFetch->insts[i]->setSquashed();
324  }
325  }
326 
327  // Clear the instruction list and skid buffer in case they have any
328  // insts in them.
329  while (!insts[tid].empty()) {
330  insts[tid].pop();
331  }
332 
333  while (!skidBuffer[tid].empty()) {
334  skidBuffer[tid].pop();
335  }
336 
337  // Squash instructions up until this one
338  cpu->removeInstsUntil(squash_seq_num, tid);
339 }
340 
341 unsigned
343 {
344  DPRINTF(Decode, "[tid:%i] Squashing.\n",tid);
345 
346  if (decodeStatus[tid] == Blocked ||
347  decodeStatus[tid] == Unblocking) {
348  if (FullSystem) {
349  toFetch->decodeUnblock[tid] = 1;
350  } else {
351  // In syscall emulation, we can have both a block and a squash due
352  // to a syscall in the same cycle. This would cause both signals
353  // to be high. This shouldn't happen in full system.
354  // @todo: Determine if this still happens.
355  if (toFetch->decodeBlock[tid])
356  toFetch->decodeBlock[tid] = 0;
357  else
358  toFetch->decodeUnblock[tid] = 1;
359  }
360  }
361 
362  // Set status to squashing.
363  decodeStatus[tid] = Squashing;
364 
365  // Go through incoming instructions from fetch and squash them.
366  unsigned squash_count = 0;
367 
368  for (int i=0; i<fromFetch->size; i++) {
369  if (fromFetch->insts[i]->threadNumber == tid) {
370  fromFetch->insts[i]->setSquashed();
371  squash_count++;
372  }
373  }
374 
375  // Clear the instruction list and skid buffer in case they have any
376  // insts in them.
377  while (!insts[tid].empty()) {
378  insts[tid].pop();
379  }
380 
381  while (!skidBuffer[tid].empty()) {
382  skidBuffer[tid].pop();
383  }
384 
385  return squash_count;
386 }
387 
388 void
390 {
391  DynInstPtr inst = NULL;
392 
393  while (!insts[tid].empty()) {
394  inst = insts[tid].front();
395 
396  insts[tid].pop();
397 
398  assert(tid == inst->threadNumber);
399 
400  skidBuffer[tid].push(inst);
401 
402  DPRINTF(Decode, "Inserting [tid:%d][sn:%lli] PC: %s into decode "
403  "skidBuffer %i\n", inst->threadNumber, inst->seqNum,
404  inst->pcState(), skidBuffer[tid].size());
405  }
406 
407  // @todo: Eventually need to enforce this by not letting a thread
408  // fetch past its skidbuffer
409  assert(skidBuffer[tid].size() <= skidBufferMax);
410 }
411 
412 bool
414 {
415  list<ThreadID>::iterator threads = activeThreads->begin();
417 
418  while (threads != end) {
419  ThreadID tid = *threads++;
420  if (!skidBuffer[tid].empty())
421  return false;
422  }
423 
424  return true;
425 }
426 
427 void
429 {
430  bool any_unblocking = false;
431 
432  list<ThreadID>::iterator threads = activeThreads->begin();
434 
435  while (threads != end) {
436  ThreadID tid = *threads++;
437 
438  if (decodeStatus[tid] == Unblocking) {
439  any_unblocking = true;
440  break;
441  }
442  }
443 
444  // Decode will have activity if it's unblocking.
445  if (any_unblocking) {
446  if (_status == Inactive) {
447  _status = Active;
448 
449  DPRINTF(Activity, "Activating stage.\n");
450 
452  }
453  } else {
454  // If it's not unblocking, then decode will not have any internal
455  // activity. Switch it to inactive.
456  if (_status == Active) {
457  _status = Inactive;
458  DPRINTF(Activity, "Deactivating stage.\n");
459 
461  }
462  }
463 }
464 
465 void
467 {
468  int insts_from_fetch = fromFetch->size;
469  for (int i = 0; i < insts_from_fetch; ++i) {
470  insts[fromFetch->insts[i]->threadNumber].push(fromFetch->insts[i]);
471  }
472 }
473 
474 void
476 {
477  if (fromRename->renameBlock[tid]) {
478  stalls[tid].rename = true;
479  }
480 
481  if (fromRename->renameUnblock[tid]) {
482  assert(stalls[tid].rename);
483  stalls[tid].rename = false;
484  }
485 }
486 
487 bool
489 {
490  // Check if there's a squash signal, squash if there is.
491  // Check stall signals, block if necessary.
492  // If status was blocked
493  // Check if stall conditions have passed
494  // if so then go to unblocking
495  // If status was Squashing
496  // check if squashing is not high. Switch to running this cycle.
497 
498  // Update the per thread stall statuses.
499  readStallSignals(tid);
500 
501  // Check squash signals from commit.
502  if (fromCommit->commitInfo[tid].squash) {
503 
504  DPRINTF(Decode, "[tid:%i] Squashing instructions due to squash "
505  "from commit.\n", tid);
506 
507  squash(tid);
508 
509  return true;
510  }
511 
512  if (checkStall(tid)) {
513  return block(tid);
514  }
515 
516  if (decodeStatus[tid] == Blocked) {
517  DPRINTF(Decode, "[tid:%i] Done blocking, switching to unblocking.\n",
518  tid);
519 
520  decodeStatus[tid] = Unblocking;
521 
522  unblock(tid);
523 
524  return true;
525  }
526 
527  if (decodeStatus[tid] == Squashing) {
528  // Switch status to running if decode isn't being told to block or
529  // squash this cycle.
530  DPRINTF(Decode, "[tid:%i] Done squashing, switching to running.\n",
531  tid);
532 
533  decodeStatus[tid] = Running;
534 
535  return false;
536  }
537 
538  // If we've reached this point, we have not gotten any signals that
539  // cause decode to change its status. Decode remains the same as before.
540  return false;
541 }
542 
543 void
545 {
546  wroteToTimeBuffer = false;
547 
548  bool status_change = false;
549 
550  toRenameIndex = 0;
551 
552  list<ThreadID>::iterator threads = activeThreads->begin();
554 
555  sortInsts();
556 
557  //Check stall and squash signals.
558  while (threads != end) {
559  ThreadID tid = *threads++;
560 
561  DPRINTF(Decode,"Processing [tid:%i]\n",tid);
562  status_change = checkSignalsAndUpdate(tid) || status_change;
563 
564  decode(status_change, tid);
565  }
566 
567  if (status_change) {
568  updateStatus();
569  }
570 
571  if (wroteToTimeBuffer) {
572  DPRINTF(Activity, "Activity this cycle.\n");
573 
575  }
576 }
577 
578 void
579 Decode::decode(bool &status_change, ThreadID tid)
580 {
581  // If status is Running or idle,
582  // call decodeInsts()
583  // If status is Unblocking,
584  // buffer any instructions coming from fetch
585  // continue trying to empty skid buffer
586  // check if stall conditions have passed
587 
588  if (decodeStatus[tid] == Blocked) {
590  } else if (decodeStatus[tid] == Squashing) {
592  }
593 
594  // Decode should try to decode as many instructions as its bandwidth
595  // will allow, as long as it is not currently blocked.
596  if (decodeStatus[tid] == Running ||
597  decodeStatus[tid] == Idle) {
598  DPRINTF(Decode, "[tid:%i] Not blocked, so attempting to run "
599  "stage.\n",tid);
600 
601  decodeInsts(tid);
602  } else if (decodeStatus[tid] == Unblocking) {
603  // Make sure that the skid buffer has something in it if the
604  // status is unblocking.
605  assert(!skidsEmpty());
606 
607  // If the status was unblocking, then instructions from the skid
608  // buffer were used. Remove those instructions and handle
609  // the rest of unblocking.
610  decodeInsts(tid);
611 
612  if (fetchInstsValid()) {
613  // Add the current inputs to the skid buffer so they can be
614  // reprocessed when this stage unblocks.
615  skidInsert(tid);
616  }
617 
618  status_change = unblock(tid) || status_change;
619  }
620 }
621 
622 void
624 {
625  // Instructions can come either from the skid buffer or the list of
626  // instructions coming from fetch, depending on decode's status.
627  int insts_available = decodeStatus[tid] == Unblocking ?
628  skidBuffer[tid].size() : insts[tid].size();
629 
630  if (insts_available == 0) {
631  DPRINTF(Decode, "[tid:%i] Nothing to do, breaking out"
632  " early.\n",tid);
633  // Should I change the status to idle?
634  ++stats.idleCycles;
635  return;
636  } else if (decodeStatus[tid] == Unblocking) {
637  DPRINTF(Decode, "[tid:%i] Unblocking, removing insts from skid "
638  "buffer.\n",tid);
640  } else if (decodeStatus[tid] == Running) {
641  ++stats.runCycles;
642  }
643 
644  std::queue<DynInstPtr>
645  &insts_to_decode = decodeStatus[tid] == Unblocking ?
646  skidBuffer[tid] : insts[tid];
647 
648  DPRINTF(Decode, "[tid:%i] Sending instruction to rename.\n",tid);
649 
650  while (insts_available > 0 && toRenameIndex < decodeWidth) {
651  assert(!insts_to_decode.empty());
652 
653  DynInstPtr inst = std::move(insts_to_decode.front());
654 
655  insts_to_decode.pop();
656 
657  DPRINTF(Decode, "[tid:%i] Processing instruction [sn:%lli] with "
658  "PC %s\n", tid, inst->seqNum, inst->pcState());
659 
660  if (inst->isSquashed()) {
661  DPRINTF(Decode, "[tid:%i] Instruction %i with PC %s is "
662  "squashed, skipping.\n",
663  tid, inst->seqNum, inst->pcState());
664 
666 
667  --insts_available;
668 
669  continue;
670  }
671 
672  // Also check if instructions have no source registers. Mark
673  // them as ready to issue at any time. Not sure if this check
674  // should exist here or at a later stage; however it doesn't matter
675  // too much for function correctness.
676  if (inst->numSrcRegs() == 0) {
677  inst->setCanIssue();
678  }
679 
680  // This current instruction is valid, so add it into the decode
681  // queue. The next instruction may not be valid, so check to
682  // see if branches were predicted correctly.
683  toRename->insts[toRenameIndex] = inst;
684 
685  ++(toRename->size);
686  ++toRenameIndex;
688  --insts_available;
689 
690 #if TRACING_ON
691  if (debug::O3PipeView) {
692  inst->decodeTick = curTick() - inst->fetchTick;
693  }
694 #endif
695 
696  // Ensure that if it was predicted as a branch, it really is a
697  // branch.
698  if (inst->readPredTaken() && !inst->isControl()) {
699  panic("Instruction predicted as a branch!");
700 
702 
703  // Might want to set some sort of boolean and just do
704  // a check at the end
705  squash(inst, inst->threadNumber);
706 
707  break;
708  }
709 
710  // Go ahead and compute any PC-relative branches.
711  // This includes direct unconditional control and
712  // direct conditional control that is predicted taken.
713  if (inst->isDirectCtrl() &&
714  (inst->isUncondCtrl() || inst->readPredTaken()))
715  {
717 
718  std::unique_ptr<PCStateBase> target = inst->branchTarget();
719  if (*target != inst->readPredTarg()) {
721 
722  // Might want to set some sort of boolean and just do
723  // a check at the end
724  squash(inst, inst->threadNumber);
725 
726  DPRINTF(Decode,
727  "[tid:%i] [sn:%llu] "
728  "Updating predictions: Wrong predicted target: %s \
729  PredPC: %s\n",
730  tid, inst->seqNum, inst->readPredTarg(), *target);
731  //The micro pc after an instruction level branch should be 0
732  inst->setPredTarg(*target);
733  break;
734  }
735  }
736  }
737 
738  // If we didn't process all instructions, then we will need to block
739  // and put all those instructions into the skid buffer.
740  if (!insts_to_decode.empty()) {
741  block(tid);
742  }
743 
744  // Record that decode has written to the time buffer for activity
745  // tracking.
746  if (toRenameIndex) {
747  wroteToTimeBuffer = true;
748  }
749 }
750 
751 } // namespace o3
752 } // 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:190
gem5::o3::CPU::DecodeIdx
@ DecodeIdx
Definition: cpu.hh:455
gem5::o3::Decode::skidBufferMax
unsigned skidBufferMax
Maximum size of the skid buffer.
Definition: decode.hh:283
gem5::o3::Decode::updateStatus
void updateStatus()
Updates overall decode status based on all of the threads' statuses.
Definition: decode.cc:428
gem5::o3::Decode::Inactive
@ Inactive
Definition: decode.hh:78
gem5::o3::Decode::sortInsts
void sortInsts()
Separates instructions from fetch into individual lists of instructions sorted by thread.
Definition: decode.cc:466
gem5::o3::Decode::commitToDecodeDelay
Cycles commitToDecodeDelay
Commit to decode delay.
Definition: decode.hh:265
gem5::o3::CPU::removeInstsUntil
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
Definition: cpu.cc:1298
gem5::o3::Decode::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: decode.cc:192
gem5::o3::Decode::block
bool block(ThreadID tid)
Switches decode to blocking, and signals back that decode has become blocked.
Definition: decode.cc:237
gem5::o3::Decode::activeThreads
std::list< ThreadID > * activeThreads
List of active thread ids.
Definition: decode.hh:280
gem5::o3::Decode::squashAfterDelaySlot
bool squashAfterDelaySlot[MaxThreads]
Tells when their is a pending delay slot inst.
Definition: decode.hh:295
gem5::o3::Decode::DecodeStats::branchResolved
statistics::Scalar branchResolved
Stat for number of times a branch is resolved at decode.
Definition: decode.hh:312
gem5::o3::Decode::clearStates
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: decode.cc:98
gem5::ArmISA::set
Bitfield< 12, 11 > set
Definition: misc_types.hh:703
gem5::o3::Decode::skidBuffer
std::queue< DynInstPtr > skidBuffer[MaxThreads]
Skid buffer between fetch and decode.
Definition: decode.hh:242
gem5::o3::Decode::fetchInstsValid
bool fetchInstsValid()
Returns if there any instructions from fetch on this cycle.
Definition: decode.cc:231
gem5::o3::Decode::Blocked
@ Blocked
Definition: decode.hh:88
gem5::o3::Decode::DecodeStats::runCycles
statistics::Scalar runCycles
Stat for total number of normal running cycles.
Definition: decode.hh:306
sc_dt::list
static scfx_rep_node * list
Definition: scfx_rep.cc:368
gem5::o3::Decode::cpu
CPU * cpu
CPU interface.
Definition: decode.hh:208
dyn_inst.hh
gem5::o3::Decode::stats
gem5::o3::Decode::DecodeStats stats
gem5::o3::Decode::DecodeStats::controlMispred
statistics::Scalar controlMispred
Stat for number of times decode detected a non-control instruction incorrectly predicted as a branch.
Definition: decode.hh:318
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
gem5::o3::Decode::fromRename
TimeBuffer< TimeStruct >::wire fromRename
Wire to get rename's output from backwards time buffer.
Definition: decode.hh:214
gem5::o3::Decode::DecodeStats::branchMispred
statistics::Scalar branchMispred
Stat for number of times a branch mispredict is detected.
Definition: decode.hh:314
gem5::o3::Decode::timeBuffer
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
Definition: decode.hh:211
gem5::RefCountingPtr< DynInst >
gem5::TimeBuffer
Definition: timebuf.hh:40
gem5::o3::Decode::wroteToTimeBuffer
bool wroteToTimeBuffer
Variable that tracks if decode has written to the time buffer this cycle.
Definition: decode.hh:247
gem5::o3::Decode::decode
void decode(bool &status_change, ThreadID tid)
Determines what to do based on decode's current status.
Definition: decode.cc:579
gem5::o3::CPU::deactivateStage
void deactivateStage(const StageIdx idx)
Changes a stage's status to inactive within the activity recorder.
Definition: cpu.hh:497
gem5::o3::Decode::DecodeStats::DecodeStats
DecodeStats(CPU *cpu)
Definition: decode.cc:123
gem5::o3::Decode::numThreads
ThreadID numThreads
number of Active Threads
Definition: decode.hh:277
gem5::o3::Decode::skidsEmpty
bool skidsEmpty()
Returns if all of the skid buffers are empty.
Definition: decode.cc:413
gem5::o3::Decode::Unblocking
@ Unblocking
Definition: decode.hh:89
gem5::o3::Decode::resetStage
void resetStage()
Definition: decode.cc:105
gem5::o3::Decode::tick
void tick()
Ticks decode, processing all input signals and decoding as many instructions as possible.
Definition: decode.cc:544
gem5::o3::Decode::fromCommit
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's information from backwards time buffer.
Definition: decode.hh:220
inst_seq.hh
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:94
gem5::o3::Decode::Active
@ Active
Definition: decode.hh:77
gem5::o3::Decode::checkSignalsAndUpdate
bool checkSignalsAndUpdate(ThreadID tid)
Checks all input signals and updates decode's status appropriately.
Definition: decode.cc:488
gem5::o3::Decode::DecodeStats::unblockCycles
statistics::Scalar unblockCycles
Stat for total number of unblocking cycles.
Definition: decode.hh:308
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::o3::Decode::squash
void squash(const DynInstPtr &inst, ThreadID tid)
Squashes if there is a PC-relative branch that was predicted incorrectly.
Definition: decode.cc:284
gem5::o3::Decode::DecodeStats::decodedInsts
statistics::Scalar decodedInsts
Stat for total number of decoded instructions.
Definition: decode.hh:320
gem5::o3::Decode::DecodeStats::blockedCycles
statistics::Scalar blockedCycles
Stat for total number of blocked cycles.
Definition: decode.hh:304
gem5::o3::Decode::isDrained
bool isDrained() const
Has the stage drained?
Definition: decode.cc:207
gem5::o3::Decode::DecodeStats::idleCycles
statistics::Scalar idleCycles
Stat for total number of idle cycles.
Definition: decode.hh:302
gem5::o3::Decode::Stalls::rename
bool rename
Definition: decode.hh:252
gem5::o3::Decode::toRenameIndex
unsigned toRenameIndex
Index of instructions being sent to rename.
Definition: decode.hh:274
gem5::o3::CPU::activateStage
void activateStage(const StageIdx idx)
Changes a stage's status to active within the activity recorder.
Definition: cpu.hh:490
gem5::o3::Decode::toRename
TimeBuffer< DecodeStruct >::wire toRename
Wire used to write any information heading to rename.
Definition: decode.hh:230
gem5::o3::Decode::Decode
Decode(CPU *_cpu, const BaseO3CPUParams &params)
Decode constructor.
Definition: decode.cc:65
gem5::o3::Decode::fromIEW
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get iew's information from backwards time buffer.
Definition: decode.hh:217
gem5::o3::Decode::stalls
Stalls stalls[MaxThreads]
Tracks which stages are telling decode to stall.
Definition: decode.hh:256
gem5::o3::Decode::insts
std::queue< DynInstPtr > insts[MaxThreads]
Queue of all instructions coming from fetch this cycle.
Definition: decode.hh:239
gem5::o3::Decode::bdelayDoneSeqNum
Addr bdelayDoneSeqNum[MaxThreads]
SeqNum of Squashing Branch Delay Instruction (used for MIPS)
Definition: decode.hh:286
gem5::o3::Decode::Running
@ Running
Definition: decode.hh:84
gem5::o3::Decode::skidInsert
void skidInsert(ThreadID tid)
Inserts a thread's instructions into the skid buffer, to be decoded once decode unblocks.
Definition: decode.cc:389
gem5::o3::MaxWidth
static constexpr int MaxWidth
Definition: limits.hh:37
gem5::o3::Decode::unblock
bool unblock(ThreadID tid)
Switches decode to unblocking if the skid buffer is empty, and signals back that decode has unblocked...
Definition: decode.cc:266
gem5::o3::Decode::DecodeStats::squashCycles
statistics::Scalar squashCycles
Stat for total number of squashing cycles.
Definition: decode.hh:310
gem5::o3::Decode::checkStall
bool checkStall(ThreadID tid) const
Checks all stall signals, and returns if any are true.
Definition: decode.cc:218
gem5::o3::Decode::DecodeStats::squashedInsts
statistics::Scalar squashedInsts
Stat for total number of squashed instructions.
Definition: decode.hh:322
gem5::o3::Decode::toFetch
TimeBuffer< TimeStruct >::wire toFetch
Wire to write information heading to previous stages.
Definition: decode.hh:224
full_system.hh
gem5::o3::Decode::decodeQueue
TimeBuffer< DecodeStruct > * decodeQueue
Decode instruction queue.
Definition: decode.hh:227
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
pcstate.hh
gem5::o3::MaxThreads
static constexpr int MaxThreads
Definition: limits.hh:38
gem5::o3::Decode::setTimeBuffer
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main backwards communication time buffer pointer.
Definition: decode.cc:160
gem5::o3::Decode::_status
DecodeStatus _status
Decode status.
Definition: decode.hh:94
gem5::o3::CPU::activityThisCycle
void activityThisCycle()
Records that there was time buffer activity this cycle.
Definition: cpu.hh:486
gem5::o3::Decode::decodeStatus
ThreadStatus decodeStatus[MaxThreads]
Per-thread status.
Definition: decode.hh:97
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:372
gem5::o3::Decode
Decode class handles both single threaded and SMT decode.
Definition: decode.hh:69
gem5::o3::Decode::fetchQueue
TimeBuffer< FetchStruct > * fetchQueue
Fetch instruction queue interface.
Definition: decode.hh:233
gem5::o3::Decode::setDecodeQueue
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
Definition: decode.cc:174
gem5::o3::Decode::fromFetch
TimeBuffer< FetchStruct >::wire fromFetch
Wire to get fetch's output from fetch queue.
Definition: decode.hh:236
gem5::o3::Decode::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: decode.cc:198
gem5::o3::Decode::Squashing
@ Squashing
Definition: decode.hh:87
gem5::statistics::Group
Statistics container.
Definition: group.hh:93
gem5::InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:40
gem5::o3::Decode::readStallSignals
void readStallSignals(ThreadID tid)
Reads all stall signals from the backwards communication timebuffer.
Definition: decode.cc:475
gem5::o3::Decode::decodeInsts
void decodeInsts(ThreadID tid)
Processes instructions from fetch and passes them on to rename.
Definition: decode.cc:623
gem5::o3::Decode::renameToDecodeDelay
Cycles renameToDecodeDelay
Rename to decode delay.
Definition: decode.hh:259
gem5::o3::Decode::squashInst
DynInstPtr squashInst[MaxThreads]
Instruction used for squashing branch (used for MIPS)
Definition: decode.hh:289
gem5::o3::Decode::decodeWidth
unsigned decodeWidth
The width of decode, in instructions.
Definition: decode.hh:271
gem5::o3::Decode::setFetchQueue
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Sets pointer to time buffer coming from fetch.
Definition: decode.cc:183
trace.hh
decode.hh
gem5::o3::Decode::fetchToDecodeDelay
Cycles fetchToDecodeDelay
Fetch to decode delay.
Definition: decode.hh:268
std::list< ThreadID >
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::o3::Decode::startupStage
void startupStage()
Definition: decode.cc:92
limits.hh
gem5::o3::Decode::Idle
@ Idle
Definition: decode.hh:85
gem5::o3::Decode::name
std::string name() const
Returns the name of decode.
Definition: decode.cc:118
gem5::o3::Decode::iewToDecodeDelay
Cycles iewToDecodeDelay
IEW to decode delay.
Definition: decode.hh:262
gem5::ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178

Generated on Sat Jun 18 2022 08:12:20 for gem5 by doxygen 1.8.17