gem5  v20.1.0.0
decode_impl.hh
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 #ifndef __CPU_O3_DECODE_IMPL_HH__
42 #define __CPU_O3_DECODE_IMPL_HH__
43 
44 #include "arch/types.hh"
45 #include "base/trace.hh"
46 #include "config/the_isa.hh"
47 #include "cpu/o3/decode.hh"
48 #include "cpu/inst_seq.hh"
49 #include "debug/Activity.hh"
50 #include "debug/Decode.hh"
51 #include "debug/O3PipeView.hh"
52 #include "params/DerivO3CPU.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 template<class Impl>
60 DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
61  : cpu(_cpu),
62  renameToDecodeDelay(params->renameToDecodeDelay),
63  iewToDecodeDelay(params->iewToDecodeDelay),
64  commitToDecodeDelay(params->commitToDecodeDelay),
65  fetchToDecodeDelay(params->fetchToDecodeDelay),
66  decodeWidth(params->decodeWidth),
67  numThreads(params->numThreads),
68  stats(_cpu)
69 {
70  if (decodeWidth > Impl::MaxWidth)
71  fatal("decodeWidth (%d) is larger than compiled limit (%d),\n"
72  "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
73  decodeWidth, static_cast<int>(Impl::MaxWidth));
74 
75  // @todo: Make into a parameter
76  skidBufferMax = (fetchToDecodeDelay + 1) * params->fetchWidth;
77  for (int tid = 0; tid < Impl::MaxThreads; tid++) {
78  stalls[tid] = {false};
79  decodeStatus[tid] = Idle;
80  bdelayDoneSeqNum[tid] = 0;
81  squashInst[tid] = nullptr;
82  squashAfterDelaySlot[tid] = 0;
83  }
84 }
85 
86 template<class Impl>
87 void
89 {
90  resetStage();
91 }
92 
93 template<class Impl>
94 void
96 {
97  decodeStatus[tid] = Idle;
98  stalls[tid].rename = false;
99 }
100 
101 template<class Impl>
102 void
104 {
105  _status = Inactive;
106 
107  // Setup status, make sure stall signals are clear.
108  for (ThreadID tid = 0; tid < numThreads; ++tid) {
109  decodeStatus[tid] = Idle;
110 
111  stalls[tid].rename = false;
112  }
113 }
114 
115 template <class Impl>
116 std::string
118 {
119  return cpu->name() + ".decode";
120 }
121 
122 template <class Impl>
124  : Stats::Group(cpu, "decode"),
125  ADD_STAT(idleCycles, "Number of cycles decode is idle"),
126  ADD_STAT(blockedCycles, "Number of cycles decode is blocked"),
127  ADD_STAT(runCycles, "Number of cycles decode is running"),
128  ADD_STAT(unblockCycles, "Number of cycles decode is unblocking"),
129  ADD_STAT(squashCycles, "Number of cycles decode is squashing"),
130  ADD_STAT(branchResolved, "Number of times decode resolved a "
131  " branch"),
132  ADD_STAT(branchMispred, "Number of times decode detected a branch"
133  " misprediction"),
134  ADD_STAT(controlMispred,"Number of times decode detected an"
135  " instruction incorrectly predicted as a control"),
136  ADD_STAT(decodedInsts, "Number of instructions handled by decode"),
137  ADD_STAT(squashedInsts, "Number of squashed instructions handled"
138  " by decode")
139 {
150 }
151 
152 template<class Impl>
153 void
155 {
156  timeBuffer = tb_ptr;
157 
158  // Setup wire to write information back to fetch.
159  toFetch = timeBuffer->getWire(0);
160 
161  // Create wires to get information from proper places in time buffer.
165 }
166 
167 template<class Impl>
168 void
170 {
171  decodeQueue = dq_ptr;
172 
173  // Setup wire to write information to proper place in decode queue.
175 }
176 
177 template<class Impl>
178 void
180 {
181  fetchQueue = fq_ptr;
182 
183  // Setup wire to read information from fetch queue.
185 }
186 
187 template<class Impl>
188 void
190 {
191  activeThreads = at_ptr;
192 }
193 
194 template <class Impl>
195 void
197 {
198  for (ThreadID tid = 0; tid < numThreads; ++tid) {
199  assert(insts[tid].empty());
200  assert(skidBuffer[tid].empty());
201  }
202 }
203 
204 template <class Impl>
205 bool
207 {
208  for (ThreadID tid = 0; tid < numThreads; ++tid) {
209  if (!insts[tid].empty() || !skidBuffer[tid].empty() ||
210  (decodeStatus[tid] != Running && decodeStatus[tid] != Idle))
211  return false;
212  }
213  return true;
214 }
215 
216 template<class Impl>
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 template<class Impl>
231 inline bool
233 {
234  return fromFetch->size > 0;
235 }
236 
237 template<class Impl>
238 bool
240 {
241  DPRINTF(Decode, "[tid:%i] Blocking.\n", tid);
242 
243  // Add the current inputs to the skid buffer so they can be
244  // reprocessed when this stage unblocks.
245  skidInsert(tid);
246 
247  // If the decode status is blocked or unblocking then decode has not yet
248  // signalled fetch to unblock. In that case, there is no need to tell
249  // fetch to block.
250  if (decodeStatus[tid] != Blocked) {
251  // Set the status to Blocked.
252  decodeStatus[tid] = Blocked;
253 
254  if (toFetch->decodeUnblock[tid]) {
255  toFetch->decodeUnblock[tid] = false;
256  } else {
257  toFetch->decodeBlock[tid] = true;
258  wroteToTimeBuffer = true;
259  }
260 
261  return true;
262  }
263 
264  return false;
265 }
266 
267 template<class Impl>
268 bool
270 {
271  // Decode is done unblocking only if the skid buffer is empty.
272  if (skidBuffer[tid].empty()) {
273  DPRINTF(Decode, "[tid:%i] Done unblocking.\n", tid);
274  toFetch->decodeUnblock[tid] = true;
275  wroteToTimeBuffer = true;
276 
277  decodeStatus[tid] = Running;
278  return true;
279  }
280 
281  DPRINTF(Decode, "[tid:%i] Currently unblocking.\n", tid);
282 
283  return false;
284 }
285 
286 template<class Impl>
287 void
289 {
290  DPRINTF(Decode, "[tid:%i] [sn:%llu] Squashing due to incorrect branch "
291  "prediction detected at decode.\n", tid, inst->seqNum);
292 
293  // Send back mispredict information.
294  toFetch->decodeInfo[tid].branchMispredict = true;
295  toFetch->decodeInfo[tid].predIncorrect = true;
296  toFetch->decodeInfo[tid].mispredictInst = inst;
297  toFetch->decodeInfo[tid].squash = true;
298  toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
299  toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
300  toFetch->decodeInfo[tid].branchTaken = inst->pcState().branching();
301  toFetch->decodeInfo[tid].squashInst = inst;
302  if (toFetch->decodeInfo[tid].mispredictInst->isUncondCtrl()) {
303  toFetch->decodeInfo[tid].branchTaken = true;
304  }
305 
306  InstSeqNum squash_seq_num = inst->seqNum;
307 
308  // Might have to tell fetch to unblock.
309  if (decodeStatus[tid] == Blocked ||
310  decodeStatus[tid] == Unblocking) {
311  toFetch->decodeUnblock[tid] = 1;
312  }
313 
314  // Set status to squashing.
315  decodeStatus[tid] = Squashing;
316 
317  for (int i=0; i<fromFetch->size; i++) {
318  if (fromFetch->insts[i]->threadNumber == tid &&
319  fromFetch->insts[i]->seqNum > squash_seq_num) {
320  fromFetch->insts[i]->setSquashed();
321  }
322  }
323 
324  // Clear the instruction list and skid buffer in case they have any
325  // insts in them.
326  while (!insts[tid].empty()) {
327  insts[tid].pop();
328  }
329 
330  while (!skidBuffer[tid].empty()) {
331  skidBuffer[tid].pop();
332  }
333 
334  // Squash instructions up until this one
335  cpu->removeInstsUntil(squash_seq_num, tid);
336 }
337 
338 template<class Impl>
339 unsigned
341 {
342  DPRINTF(Decode, "[tid:%i] Squashing.\n",tid);
343 
344  if (decodeStatus[tid] == Blocked ||
345  decodeStatus[tid] == Unblocking) {
346  if (FullSystem) {
347  toFetch->decodeUnblock[tid] = 1;
348  } else {
349  // In syscall emulation, we can have both a block and a squash due
350  // to a syscall in the same cycle. This would cause both signals
351  // to be high. This shouldn't happen in full system.
352  // @todo: Determine if this still happens.
353  if (toFetch->decodeBlock[tid])
354  toFetch->decodeBlock[tid] = 0;
355  else
356  toFetch->decodeUnblock[tid] = 1;
357  }
358  }
359 
360  // Set status to squashing.
361  decodeStatus[tid] = Squashing;
362 
363  // Go through incoming instructions from fetch and squash them.
364  unsigned squash_count = 0;
365 
366  for (int i=0; i<fromFetch->size; i++) {
367  if (fromFetch->insts[i]->threadNumber == tid) {
368  fromFetch->insts[i]->setSquashed();
369  squash_count++;
370  }
371  }
372 
373  // Clear the instruction list and skid buffer in case they have any
374  // insts in them.
375  while (!insts[tid].empty()) {
376  insts[tid].pop();
377  }
378 
379  while (!skidBuffer[tid].empty()) {
380  skidBuffer[tid].pop();
381  }
382 
383  return squash_count;
384 }
385 
386 template<class Impl>
387 void
389 {
390  DynInstPtr inst = NULL;
391 
392  while (!insts[tid].empty()) {
393  inst = insts[tid].front();
394 
395  insts[tid].pop();
396 
397  assert(tid == inst->threadNumber);
398 
399  skidBuffer[tid].push(inst);
400 
401  DPRINTF(Decode,"Inserting [tid:%d][sn:%lli] PC: %s into decode skidBuffer %i\n",
402  inst->threadNumber, inst->seqNum, inst->pcState(), skidBuffer[tid].size());
403  }
404 
405  // @todo: Eventually need to enforce this by not letting a thread
406  // fetch past its skidbuffer
407  assert(skidBuffer[tid].size() <= skidBufferMax);
408 }
409 
410 template<class Impl>
411 bool
413 {
414  list<ThreadID>::iterator threads = activeThreads->begin();
416 
417  while (threads != end) {
418  ThreadID tid = *threads++;
419  if (!skidBuffer[tid].empty())
420  return false;
421  }
422 
423  return true;
424 }
425 
426 template<class Impl>
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 
451  cpu->activateStage(O3CPU::DecodeIdx);
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 
460  cpu->deactivateStage(O3CPU::DecodeIdx);
461  }
462  }
463 }
464 
465 template <class Impl>
466 void
468 {
469  int insts_from_fetch = fromFetch->size;
470  for (int i = 0; i < insts_from_fetch; ++i) {
471  insts[fromFetch->insts[i]->threadNumber].push(fromFetch->insts[i]);
472  }
473 }
474 
475 template<class Impl>
476 void
478 {
479  if (fromRename->renameBlock[tid]) {
480  stalls[tid].rename = true;
481  }
482 
483  if (fromRename->renameUnblock[tid]) {
484  assert(stalls[tid].rename);
485  stalls[tid].rename = false;
486  }
487 }
488 
489 template <class Impl>
490 bool
492 {
493  // Check if there's a squash signal, squash if there is.
494  // Check stall signals, block if necessary.
495  // If status was blocked
496  // Check if stall conditions have passed
497  // if so then go to unblocking
498  // If status was Squashing
499  // check if squashing is not high. Switch to running this cycle.
500 
501  // Update the per thread stall statuses.
502  readStallSignals(tid);
503 
504  // Check squash signals from commit.
505  if (fromCommit->commitInfo[tid].squash) {
506 
507  DPRINTF(Decode, "[tid:%i] Squashing instructions due to squash "
508  "from commit.\n", tid);
509 
510  squash(tid);
511 
512  return true;
513  }
514 
515  if (checkStall(tid)) {
516  return block(tid);
517  }
518 
519  if (decodeStatus[tid] == Blocked) {
520  DPRINTF(Decode, "[tid:%i] Done blocking, switching to unblocking.\n",
521  tid);
522 
523  decodeStatus[tid] = Unblocking;
524 
525  unblock(tid);
526 
527  return true;
528  }
529 
530  if (decodeStatus[tid] == Squashing) {
531  // Switch status to running if decode isn't being told to block or
532  // squash this cycle.
533  DPRINTF(Decode, "[tid:%i] Done squashing, switching to running.\n",
534  tid);
535 
536  decodeStatus[tid] = Running;
537 
538  return false;
539  }
540 
541  // If we've reached this point, we have not gotten any signals that
542  // cause decode to change its status. Decode remains the same as before.
543  return false;
544 }
545 
546 template<class Impl>
547 void
549 {
550  wroteToTimeBuffer = false;
551 
552  bool status_change = false;
553 
554  toRenameIndex = 0;
555 
556  list<ThreadID>::iterator threads = activeThreads->begin();
558 
559  sortInsts();
560 
561  //Check stall and squash signals.
562  while (threads != end) {
563  ThreadID tid = *threads++;
564 
565  DPRINTF(Decode,"Processing [tid:%i]\n",tid);
566  status_change = checkSignalsAndUpdate(tid) || status_change;
567 
568  decode(status_change, tid);
569  }
570 
571  if (status_change) {
572  updateStatus();
573  }
574 
575  if (wroteToTimeBuffer) {
576  DPRINTF(Activity, "Activity this cycle.\n");
577 
578  cpu->activityThisCycle();
579  }
580 }
581 
582 template<class Impl>
583 void
584 DefaultDecode<Impl>::decode(bool &status_change, ThreadID tid)
585 {
586  // If status is Running or idle,
587  // call decodeInsts()
588  // If status is Unblocking,
589  // buffer any instructions coming from fetch
590  // continue trying to empty skid buffer
591  // check if stall conditions have passed
592 
593  if (decodeStatus[tid] == Blocked) {
595  } else if (decodeStatus[tid] == Squashing) {
597  }
598 
599  // Decode should try to decode as many instructions as its bandwidth
600  // will allow, as long as it is not currently blocked.
601  if (decodeStatus[tid] == Running ||
602  decodeStatus[tid] == Idle) {
603  DPRINTF(Decode, "[tid:%i] Not blocked, so attempting to run "
604  "stage.\n",tid);
605 
606  decodeInsts(tid);
607  } else if (decodeStatus[tid] == Unblocking) {
608  // Make sure that the skid buffer has something in it if the
609  // status is unblocking.
610  assert(!skidsEmpty());
611 
612  // If the status was unblocking, then instructions from the skid
613  // buffer were used. Remove those instructions and handle
614  // the rest of unblocking.
615  decodeInsts(tid);
616 
617  if (fetchInstsValid()) {
618  // Add the current inputs to the skid buffer so they can be
619  // reprocessed when this stage unblocks.
620  skidInsert(tid);
621  }
622 
623  status_change = unblock(tid) || status_change;
624  }
625 }
626 
627 template <class Impl>
628 void
630 {
631  // Instructions can come either from the skid buffer or the list of
632  // instructions coming from fetch, depending on decode's status.
633  int insts_available = decodeStatus[tid] == Unblocking ?
634  skidBuffer[tid].size() : insts[tid].size();
635 
636  if (insts_available == 0) {
637  DPRINTF(Decode, "[tid:%i] Nothing to do, breaking out"
638  " early.\n",tid);
639  // Should I change the status to idle?
640  ++stats.idleCycles;
641  return;
642  } else if (decodeStatus[tid] == Unblocking) {
643  DPRINTF(Decode, "[tid:%i] Unblocking, removing insts from skid "
644  "buffer.\n",tid);
646  } else if (decodeStatus[tid] == Running) {
647  ++stats.runCycles;
648  }
649 
650  std::queue<DynInstPtr>
651  &insts_to_decode = decodeStatus[tid] == Unblocking ?
652  skidBuffer[tid] : insts[tid];
653 
654  DPRINTF(Decode, "[tid:%i] Sending instruction to rename.\n",tid);
655 
656  while (insts_available > 0 && toRenameIndex < decodeWidth) {
657  assert(!insts_to_decode.empty());
658 
659  DynInstPtr inst = std::move(insts_to_decode.front());
660 
661  insts_to_decode.pop();
662 
663  DPRINTF(Decode, "[tid:%i] Processing instruction [sn:%lli] with "
664  "PC %s\n", tid, inst->seqNum, inst->pcState());
665 
666  if (inst->isSquashed()) {
667  DPRINTF(Decode, "[tid:%i] Instruction %i with PC %s is "
668  "squashed, skipping.\n",
669  tid, inst->seqNum, inst->pcState());
670 
672 
673  --insts_available;
674 
675  continue;
676  }
677 
678  // Also check if instructions have no source registers. Mark
679  // them as ready to issue at any time. Not sure if this check
680  // should exist here or at a later stage; however it doesn't matter
681  // too much for function correctness.
682  if (inst->numSrcRegs() == 0) {
683  inst->setCanIssue();
684  }
685 
686  // This current instruction is valid, so add it into the decode
687  // queue. The next instruction may not be valid, so check to
688  // see if branches were predicted correctly.
689  toRename->insts[toRenameIndex] = inst;
690 
691  ++(toRename->size);
692  ++toRenameIndex;
694  --insts_available;
695 
696 #if TRACING_ON
697  if (DTRACE(O3PipeView)) {
698  inst->decodeTick = curTick() - inst->fetchTick;
699  }
700 #endif
701 
702  // Ensure that if it was predicted as a branch, it really is a
703  // branch.
704  if (inst->readPredTaken() && !inst->isControl()) {
705  panic("Instruction predicted as a branch!");
706 
708 
709  // Might want to set some sort of boolean and just do
710  // a check at the end
711  squash(inst, inst->threadNumber);
712 
713  break;
714  }
715 
716  // Go ahead and compute any PC-relative branches.
717  // This includes direct unconditional control and
718  // direct conditional control that is predicted taken.
719  if (inst->isDirectCtrl() &&
720  (inst->isUncondCtrl() || inst->readPredTaken()))
721  {
723 
724  if (!(inst->branchTarget() == inst->readPredTarg())) {
726 
727  // Might want to set some sort of boolean and just do
728  // a check at the end
729  squash(inst, inst->threadNumber);
730  TheISA::PCState target = inst->branchTarget();
731 
732  DPRINTF(Decode,
733  "[tid:%i] [sn:%llu] "
734  "Updating predictions: Wrong predicted target: %s \
735  PredPC: %s\n",
736  tid, inst->seqNum, inst->readPredTarg(), target);
737  //The micro pc after an instruction level branch should be 0
738  inst->setPredTarg(target);
739  break;
740  }
741  }
742  }
743 
744  // If we didn't process all instructions, then we will need to block
745  // and put all those instructions into the skid buffer.
746  if (!insts_to_decode.empty()) {
747  block(tid);
748  }
749 
750  // Record that decode has written to the time buffer for activity
751  // tracking.
752  if (toRenameIndex) {
753  wroteToTimeBuffer = true;
754  }
755 }
756 
757 #endif//__CPU_O3_DECODE_IMPL_HH__
DefaultDecode::squash
void squash(const DynInstPtr &inst, ThreadID tid)
Squashes if there is a PC-relative branch that was predicted incorrectly.
Definition: decode_impl.hh:288
DefaultDecode::DecodeStats::squashCycles
Stats::Scalar squashCycles
Stat for total number of squashing cycles.
Definition: decode.hh:307
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
DefaultDecode::bdelayDoneSeqNum
Addr bdelayDoneSeqNum[Impl::MaxThreads]
SeqNum of Squashing Branch Delay Instruction (used for MIPS)
Definition: decode.hh:284
DefaultDecode::timeBuffer
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
Definition: decode.hh:210
DefaultDecode::renameToDecodeDelay
Cycles renameToDecodeDelay
Rename to decode delay.
Definition: decode.hh:257
DefaultDecode::checkStall
bool checkStall(ThreadID tid) const
Checks all stall signals, and returns if any are true.
Definition: decode_impl.hh:218
DefaultDecode::DecodeStats::decodedInsts
Stats::Scalar decodedInsts
Stat for total number of decoded instructions.
Definition: decode.hh:317
DefaultDecode::Squashing
@ Squashing
Definition: decode.hh:86
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
DefaultDecode::checkSignalsAndUpdate
bool checkSignalsAndUpdate(ThreadID tid)
Checks all input signals and updates decode's status appropriately.
Definition: decode_impl.hh:491
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
DefaultDecode::insts
std::queue< DynInstPtr > insts[Impl::MaxThreads]
Queue of all instructions coming from fetch this cycle.
Definition: decode.hh:238
DefaultDecode::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: decode_impl.hh:189
sc_dt::list
static scfx_rep_node * list
Definition: scfx_rep.cc:368
DefaultDecode::decodeStatus
ThreadStatus decodeStatus[Impl::MaxThreads]
Per-thread status.
Definition: decode.hh:96
DefaultDecode::DecodeStats::runCycles
Stats::Scalar runCycles
Stat for total number of normal running cycles.
Definition: decode.hh:303
DTRACE
#define DTRACE(x)
Definition: debug.hh:146
FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:132
DefaultDecode::O3CPU
Impl::O3CPU O3CPU
Definition: decode.hh:63
DefaultDecode::iewToDecodeDelay
Cycles iewToDecodeDelay
IEW to decode delay.
Definition: decode.hh:260
TimeBuffer::size
unsigned size
Definition: timebuf.hh:42
DefaultDecode::squashAfterDelaySlot
bool squashAfterDelaySlot[Impl::MaxThreads]
Tells when their is a pending delay slot inst.
Definition: decode.hh:293
DefaultDecode::fromRename
TimeBuffer< TimeStruct >::wire fromRename
Wire to get rename's output from backwards time buffer.
Definition: decode.hh:213
DefaultDecode::DynInstPtr
Impl::DynInstPtr DynInstPtr
Definition: decode.hh:64
TimeBuffer< TimeStruct >
DefaultDecode::name
std::string name() const
Returns the name of decode.
Definition: decode_impl.hh:117
DefaultDecode::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: decode_impl.hh:196
DefaultDecode::toRenameIndex
unsigned toRenameIndex
Index of instructions being sent to rename.
Definition: decode.hh:272
DefaultDecode::setTimeBuffer
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main backwards communication time buffer pointer.
Definition: decode_impl.hh:154
DefaultDecode::DecodeStats::unblockCycles
Stats::Scalar unblockCycles
Stat for total number of unblocking cycles.
Definition: decode.hh:305
DefaultDecode::DecodeStats::DecodeStats
DecodeStats(O3CPU *cpu)
Definition: decode_impl.hh:123
DefaultDecode::fromCommit
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's information from backwards time buffer.
Definition: decode.hh:219
DefaultDecode::Active
@ Active
Definition: decode.hh:77
DefaultDecode::skidInsert
void skidInsert(ThreadID tid)
Inserts a thread's instructions into the skid buffer, to be decoded once decode unblocks.
Definition: decode_impl.hh:388
DefaultDecode::resetStage
void resetStage()
Definition: decode_impl.hh:103
DefaultDecode::block
bool block(ThreadID tid)
Switches decode to blocking, and signals back that decode has become blocked.
Definition: decode_impl.hh:239
inst_seq.hh
Stats::DataWrap::prereq
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:345
DefaultDecode::Idle
@ Idle
Definition: decode.hh:84
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:67
DefaultDecode::DecodeStats::blockedCycles
Stats::Scalar blockedCycles
Stat for total number of blocked cycles.
Definition: decode.hh:301
DefaultDecode::DecodeStats::controlMispred
Stats::Scalar controlMispred
Stat for number of times decode detected a non-control instruction incorrectly predicted as a branch.
Definition: decode.hh:315
DefaultDecode::activeThreads
std::list< ThreadID > * activeThreads
List of active thread ids.
Definition: decode.hh:278
DefaultDecode::skidBuffer
std::queue< DynInstPtr > skidBuffer[Impl::MaxThreads]
Skid buffer between fetch and decode.
Definition: decode.hh:241
DefaultDecode::Inactive
@ Inactive
Definition: decode.hh:78
DefaultDecode::DecodeStats::idleCycles
Stats::Scalar idleCycles
Stat for total number of idle cycles.
Definition: decode.hh:299
InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:37
DefaultDecode::toFetch
TimeBuffer< TimeStruct >::wire toFetch
Wire to write information heading to previous stages.
Definition: decode.hh:223
DefaultDecode::DecodeStats::branchMispred
Stats::Scalar branchMispred
Stat for number of times a branch mispredict is detected.
Definition: decode.hh:311
DefaultDecode::cpu
O3CPU * cpu
CPU interface.
Definition: decode.hh:207
DefaultDecode::stalls
Stalls stalls[Impl::MaxThreads]
Tracks which stages are telling decode to stall.
Definition: decode.hh:254
DefaultDecode::_status
DecodeStatus _status
Decode status.
Definition: decode.hh:93
DefaultDecode::fromFetch
TimeBuffer< FetchStruct >::wire fromFetch
Wire to get fetch's output from fetch queue.
Definition: decode.hh:235
DefaultDecode::fetchInstsValid
bool fetchInstsValid()
Returns if there any instructions from fetch on this cycle.
Definition: decode_impl.hh:232
DefaultDecode::clearStates
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: decode_impl.hh:95
DefaultDecode::Stalls::rename
bool rename
Definition: decode.hh:250
DefaultDecode::startupStage
void startupStage()
Definition: decode_impl.hh:88
full_system.hh
DefaultDecode::toRename
TimeBuffer< DecodeStruct >::wire toRename
Wire used to write any information heading to rename.
Definition: decode.hh:229
DefaultDecode::updateStatus
void updateStatus()
Updates overall decode status based on all of the threads' statuses.
Definition: decode_impl.hh:428
DefaultDecode::sortInsts
void sortInsts()
Separates instructions from fetch into individual lists of instructions sorted by thread.
Definition: decode_impl.hh:467
DefaultDecode::decodeInsts
void decodeInsts(ThreadID tid)
Processes instructions from fetch and passes them on to rename.
Definition: decode_impl.hh:629
DefaultDecode::Unblocking
@ Unblocking
Definition: decode.hh:88
DefaultDecode::tick
void tick()
Ticks decode, processing all input signals and decoding as many instructions as possible.
Definition: decode_impl.hh:548
DefaultDecode::Running
@ Running
Definition: decode.hh:83
DefaultDecode::DecodeStats::squashedInsts
Stats::Scalar squashedInsts
Stat for total number of squashed instructions.
Definition: decode.hh:319
DefaultDecode::decodeWidth
unsigned decodeWidth
The width of decode, in instructions.
Definition: decode.hh:269
DefaultDecode::stats
DefaultDecode::DecodeStats stats
DefaultDecode::skidsEmpty
bool skidsEmpty()
Returns if all of the skid buffers are empty.
Definition: decode_impl.hh:412
MipsISA::PCState
GenericISA::DelaySlotPCState< MachInst > PCState
Definition: types.hh:41
DefaultDecode::decodeQueue
TimeBuffer< DecodeStruct > * decodeQueue
Decode instruction queue.
Definition: decode.hh:226
DefaultDecode::wroteToTimeBuffer
bool wroteToTimeBuffer
Variable that tracks if decode has written to the time buffer this cycle.
Definition: decode.hh:246
DefaultDecode::fetchQueue
TimeBuffer< FetchStruct > * fetchQueue
Fetch instruction queue interface.
Definition: decode.hh:232
DefaultDecode::squashInst
DynInstPtr squashInst[Impl::MaxThreads]
Instruction used for squashing branch (used for MIPS)
Definition: decode.hh:287
DefaultDecode::setFetchQueue
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Sets pointer to time buffer coming from fetch.
Definition: decode_impl.hh:179
DefaultDecode::setDecodeQueue
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
Definition: decode_impl.hh:169
Stats
Definition: statistics.cc:61
trace.hh
DefaultDecode::Blocked
@ Blocked
Definition: decode.hh:87
decode.hh
DefaultDecode::isDrained
bool isDrained() const
Has the stage drained?
Definition: decode_impl.hh:206
DefaultDecode::DecodeStats::branchResolved
Stats::Scalar branchResolved
Stat for number of times a branch is resolved at decode.
Definition: decode.hh:309
DefaultDecode::decode
void decode(bool &status_change, ThreadID tid)
Determines what to do based on decode's current status.
Definition: decode_impl.hh:584
DefaultDecode::numThreads
ThreadID numThreads
number of Active Threads
Definition: decode.hh:275
std::list< ThreadID >
DefaultDecode::DefaultDecode
DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
DefaultDecode constructor.
Definition: decode_impl.hh:60
DefaultDecode::unblock
bool unblock(ThreadID tid)
Switches decode to unblocking if the skid buffer is empty, and signals back that decode has unblocked...
Definition: decode_impl.hh:269
DefaultDecode::skidBufferMax
unsigned skidBufferMax
Maximum size of the skid buffer.
Definition: decode.hh:281
DefaultDecode::commitToDecodeDelay
Cycles commitToDecodeDelay
Commit to decode delay.
Definition: decode.hh:263
DefaultDecode::fromIEW
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get iew's information from backwards time buffer.
Definition: decode.hh:216
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
DefaultDecode::fetchToDecodeDelay
Cycles fetchToDecodeDelay
Fetch to decode delay.
Definition: decode.hh:266
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
DefaultDecode::readStallSignals
void readStallSignals(ThreadID tid)
Reads all stall signals from the backwards communication timebuffer.
Definition: decode_impl.hh:477
TimeBuffer::getWire
wire getWire(int idx)
Definition: timebuf.hh:229

Generated on Wed Sep 30 2020 14:02:09 for gem5 by doxygen 1.8.17