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

Generated on Fri Feb 28 2020 16:26:59 for gem5 by doxygen 1.8.13