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

Generated on Mon Jun 8 2020 15:45:08 for gem5 by doxygen 1.8.13