gem5  v21.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 
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, const 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, UNIT_CYCLE, "Number of cycles decode is idle"),
126  ADD_STAT(blockedCycles, UNIT_CYCLE,
127  "Number of cycles decode is blocked"),
128  ADD_STAT(runCycles, UNIT_CYCLE, "Number of cycles decode is running"),
129  ADD_STAT(unblockCycles, UNIT_CYCLE,
130  "Number of cycles decode is unblocking"),
131  ADD_STAT(squashCycles, UNIT_CYCLE,
132  "Number of cycles decode is squashing"),
133  ADD_STAT(branchResolved, UNIT_COUNT,
134  "Number of times decode resolved a branch"),
135  ADD_STAT(branchMispred, UNIT_COUNT,
136  "Number of times decode detected a branch misprediction"),
137  ADD_STAT(controlMispred, UNIT_COUNT,
138  "Number of times decode detected an instruction incorrectly "
139  "predicted as a control"),
140  ADD_STAT(decodedInsts, UNIT_COUNT,
141  "Number of instructions handled by decode"),
142  ADD_STAT(squashedInsts, UNIT_COUNT,
143  "Number of squashed instructions handled by decode")
144 {
155 }
156 
157 template<class Impl>
158 void
160 {
161  timeBuffer = tb_ptr;
162 
163  // Setup wire to write information back to fetch.
164  toFetch = timeBuffer->getWire(0);
165 
166  // Create wires to get information from proper places in time buffer.
170 }
171 
172 template<class Impl>
173 void
175 {
176  decodeQueue = dq_ptr;
177 
178  // Setup wire to write information to proper place in decode queue.
180 }
181 
182 template<class Impl>
183 void
185 {
186  fetchQueue = fq_ptr;
187 
188  // Setup wire to read information from fetch queue.
190 }
191 
192 template<class Impl>
193 void
195 {
196  activeThreads = at_ptr;
197 }
198 
199 template <class Impl>
200 void
202 {
203  for (ThreadID tid = 0; tid < numThreads; ++tid) {
204  assert(insts[tid].empty());
205  assert(skidBuffer[tid].empty());
206  }
207 }
208 
209 template <class Impl>
210 bool
212 {
213  for (ThreadID tid = 0; tid < numThreads; ++tid) {
214  if (!insts[tid].empty() || !skidBuffer[tid].empty() ||
215  (decodeStatus[tid] != Running && decodeStatus[tid] != Idle))
216  return false;
217  }
218  return true;
219 }
220 
221 template<class Impl>
222 bool
224 {
225  bool ret_val = false;
226 
227  if (stalls[tid].rename) {
228  DPRINTF(Decode,"[tid:%i] Stall fom Rename stage detected.\n", tid);
229  ret_val = true;
230  }
231 
232  return ret_val;
233 }
234 
235 template<class Impl>
236 inline bool
238 {
239  return fromFetch->size > 0;
240 }
241 
242 template<class Impl>
243 bool
245 {
246  DPRINTF(Decode, "[tid:%i] Blocking.\n", tid);
247 
248  // Add the current inputs to the skid buffer so they can be
249  // reprocessed when this stage unblocks.
250  skidInsert(tid);
251 
252  // If the decode status is blocked or unblocking then decode has not yet
253  // signalled fetch to unblock. In that case, there is no need to tell
254  // fetch to block.
255  if (decodeStatus[tid] != Blocked) {
256  // Set the status to Blocked.
257  decodeStatus[tid] = Blocked;
258 
259  if (toFetch->decodeUnblock[tid]) {
260  toFetch->decodeUnblock[tid] = false;
261  } else {
262  toFetch->decodeBlock[tid] = true;
263  wroteToTimeBuffer = true;
264  }
265 
266  return true;
267  }
268 
269  return false;
270 }
271 
272 template<class Impl>
273 bool
275 {
276  // Decode is done unblocking only if the skid buffer is empty.
277  if (skidBuffer[tid].empty()) {
278  DPRINTF(Decode, "[tid:%i] Done unblocking.\n", tid);
279  toFetch->decodeUnblock[tid] = true;
280  wroteToTimeBuffer = true;
281 
282  decodeStatus[tid] = Running;
283  return true;
284  }
285 
286  DPRINTF(Decode, "[tid:%i] Currently unblocking.\n", tid);
287 
288  return false;
289 }
290 
291 template<class Impl>
292 void
294 {
295  DPRINTF(Decode, "[tid:%i] [sn:%llu] Squashing due to incorrect branch "
296  "prediction detected at decode.\n", tid, inst->seqNum);
297 
298  // Send back mispredict information.
299  toFetch->decodeInfo[tid].branchMispredict = true;
300  toFetch->decodeInfo[tid].predIncorrect = true;
301  toFetch->decodeInfo[tid].mispredictInst = inst;
302  toFetch->decodeInfo[tid].squash = true;
303  toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
304  toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
305  toFetch->decodeInfo[tid].branchTaken = inst->pcState().branching();
306  toFetch->decodeInfo[tid].squashInst = inst;
307  if (toFetch->decodeInfo[tid].mispredictInst->isUncondCtrl()) {
308  toFetch->decodeInfo[tid].branchTaken = true;
309  }
310 
311  InstSeqNum squash_seq_num = inst->seqNum;
312 
313  // Might have to tell fetch to unblock.
314  if (decodeStatus[tid] == Blocked ||
315  decodeStatus[tid] == Unblocking) {
316  toFetch->decodeUnblock[tid] = 1;
317  }
318 
319  // Set status to squashing.
320  decodeStatus[tid] = Squashing;
321 
322  for (int i=0; i<fromFetch->size; i++) {
323  if (fromFetch->insts[i]->threadNumber == tid &&
324  fromFetch->insts[i]->seqNum > squash_seq_num) {
325  fromFetch->insts[i]->setSquashed();
326  }
327  }
328 
329  // Clear the instruction list and skid buffer in case they have any
330  // insts in them.
331  while (!insts[tid].empty()) {
332  insts[tid].pop();
333  }
334 
335  while (!skidBuffer[tid].empty()) {
336  skidBuffer[tid].pop();
337  }
338 
339  // Squash instructions up until this one
340  cpu->removeInstsUntil(squash_seq_num, tid);
341 }
342 
343 template<class Impl>
344 unsigned
346 {
347  DPRINTF(Decode, "[tid:%i] Squashing.\n",tid);
348 
349  if (decodeStatus[tid] == Blocked ||
350  decodeStatus[tid] == Unblocking) {
351  if (FullSystem) {
352  toFetch->decodeUnblock[tid] = 1;
353  } else {
354  // In syscall emulation, we can have both a block and a squash due
355  // to a syscall in the same cycle. This would cause both signals
356  // to be high. This shouldn't happen in full system.
357  // @todo: Determine if this still happens.
358  if (toFetch->decodeBlock[tid])
359  toFetch->decodeBlock[tid] = 0;
360  else
361  toFetch->decodeUnblock[tid] = 1;
362  }
363  }
364 
365  // Set status to squashing.
366  decodeStatus[tid] = Squashing;
367 
368  // Go through incoming instructions from fetch and squash them.
369  unsigned squash_count = 0;
370 
371  for (int i=0; i<fromFetch->size; i++) {
372  if (fromFetch->insts[i]->threadNumber == tid) {
373  fromFetch->insts[i]->setSquashed();
374  squash_count++;
375  }
376  }
377 
378  // Clear the instruction list and skid buffer in case they have any
379  // insts in them.
380  while (!insts[tid].empty()) {
381  insts[tid].pop();
382  }
383 
384  while (!skidBuffer[tid].empty()) {
385  skidBuffer[tid].pop();
386  }
387 
388  return squash_count;
389 }
390 
391 template<class Impl>
392 void
394 {
395  DynInstPtr inst = NULL;
396 
397  while (!insts[tid].empty()) {
398  inst = insts[tid].front();
399 
400  insts[tid].pop();
401 
402  assert(tid == inst->threadNumber);
403 
404  skidBuffer[tid].push(inst);
405 
406  DPRINTF(Decode,"Inserting [tid:%d][sn:%lli] PC: %s into decode skidBuffer %i\n",
407  inst->threadNumber, inst->seqNum, inst->pcState(), skidBuffer[tid].size());
408  }
409 
410  // @todo: Eventually need to enforce this by not letting a thread
411  // fetch past its skidbuffer
412  assert(skidBuffer[tid].size() <= skidBufferMax);
413 }
414 
415 template<class Impl>
416 bool
418 {
419  list<ThreadID>::iterator threads = activeThreads->begin();
421 
422  while (threads != end) {
423  ThreadID tid = *threads++;
424  if (!skidBuffer[tid].empty())
425  return false;
426  }
427 
428  return true;
429 }
430 
431 template<class Impl>
432 void
434 {
435  bool any_unblocking = false;
436 
437  list<ThreadID>::iterator threads = activeThreads->begin();
439 
440  while (threads != end) {
441  ThreadID tid = *threads++;
442 
443  if (decodeStatus[tid] == Unblocking) {
444  any_unblocking = true;
445  break;
446  }
447  }
448 
449  // Decode will have activity if it's unblocking.
450  if (any_unblocking) {
451  if (_status == Inactive) {
452  _status = Active;
453 
454  DPRINTF(Activity, "Activating stage.\n");
455 
456  cpu->activateStage(O3CPU::DecodeIdx);
457  }
458  } else {
459  // If it's not unblocking, then decode will not have any internal
460  // activity. Switch it to inactive.
461  if (_status == Active) {
462  _status = Inactive;
463  DPRINTF(Activity, "Deactivating stage.\n");
464 
465  cpu->deactivateStage(O3CPU::DecodeIdx);
466  }
467  }
468 }
469 
470 template <class Impl>
471 void
473 {
474  int insts_from_fetch = fromFetch->size;
475  for (int i = 0; i < insts_from_fetch; ++i) {
476  insts[fromFetch->insts[i]->threadNumber].push(fromFetch->insts[i]);
477  }
478 }
479 
480 template<class Impl>
481 void
483 {
484  if (fromRename->renameBlock[tid]) {
485  stalls[tid].rename = true;
486  }
487 
488  if (fromRename->renameUnblock[tid]) {
489  assert(stalls[tid].rename);
490  stalls[tid].rename = false;
491  }
492 }
493 
494 template <class Impl>
495 bool
497 {
498  // Check if there's a squash signal, squash if there is.
499  // Check stall signals, block if necessary.
500  // If status was blocked
501  // Check if stall conditions have passed
502  // if so then go to unblocking
503  // If status was Squashing
504  // check if squashing is not high. Switch to running this cycle.
505 
506  // Update the per thread stall statuses.
507  readStallSignals(tid);
508 
509  // Check squash signals from commit.
510  if (fromCommit->commitInfo[tid].squash) {
511 
512  DPRINTF(Decode, "[tid:%i] Squashing instructions due to squash "
513  "from commit.\n", tid);
514 
515  squash(tid);
516 
517  return true;
518  }
519 
520  if (checkStall(tid)) {
521  return block(tid);
522  }
523 
524  if (decodeStatus[tid] == Blocked) {
525  DPRINTF(Decode, "[tid:%i] Done blocking, switching to unblocking.\n",
526  tid);
527 
528  decodeStatus[tid] = Unblocking;
529 
530  unblock(tid);
531 
532  return true;
533  }
534 
535  if (decodeStatus[tid] == Squashing) {
536  // Switch status to running if decode isn't being told to block or
537  // squash this cycle.
538  DPRINTF(Decode, "[tid:%i] Done squashing, switching to running.\n",
539  tid);
540 
541  decodeStatus[tid] = Running;
542 
543  return false;
544  }
545 
546  // If we've reached this point, we have not gotten any signals that
547  // cause decode to change its status. Decode remains the same as before.
548  return false;
549 }
550 
551 template<class Impl>
552 void
554 {
555  wroteToTimeBuffer = false;
556 
557  bool status_change = false;
558 
559  toRenameIndex = 0;
560 
561  list<ThreadID>::iterator threads = activeThreads->begin();
563 
564  sortInsts();
565 
566  //Check stall and squash signals.
567  while (threads != end) {
568  ThreadID tid = *threads++;
569 
570  DPRINTF(Decode,"Processing [tid:%i]\n",tid);
571  status_change = checkSignalsAndUpdate(tid) || status_change;
572 
573  decode(status_change, tid);
574  }
575 
576  if (status_change) {
577  updateStatus();
578  }
579 
580  if (wroteToTimeBuffer) {
581  DPRINTF(Activity, "Activity this cycle.\n");
582 
583  cpu->activityThisCycle();
584  }
585 }
586 
587 template<class Impl>
588 void
589 DefaultDecode<Impl>::decode(bool &status_change, ThreadID tid)
590 {
591  // If status is Running or idle,
592  // call decodeInsts()
593  // If status is Unblocking,
594  // buffer any instructions coming from fetch
595  // continue trying to empty skid buffer
596  // check if stall conditions have passed
597 
598  if (decodeStatus[tid] == Blocked) {
600  } else if (decodeStatus[tid] == Squashing) {
602  }
603 
604  // Decode should try to decode as many instructions as its bandwidth
605  // will allow, as long as it is not currently blocked.
606  if (decodeStatus[tid] == Running ||
607  decodeStatus[tid] == Idle) {
608  DPRINTF(Decode, "[tid:%i] Not blocked, so attempting to run "
609  "stage.\n",tid);
610 
611  decodeInsts(tid);
612  } else if (decodeStatus[tid] == Unblocking) {
613  // Make sure that the skid buffer has something in it if the
614  // status is unblocking.
615  assert(!skidsEmpty());
616 
617  // If the status was unblocking, then instructions from the skid
618  // buffer were used. Remove those instructions and handle
619  // the rest of unblocking.
620  decodeInsts(tid);
621 
622  if (fetchInstsValid()) {
623  // Add the current inputs to the skid buffer so they can be
624  // reprocessed when this stage unblocks.
625  skidInsert(tid);
626  }
627 
628  status_change = unblock(tid) || status_change;
629  }
630 }
631 
632 template <class Impl>
633 void
635 {
636  // Instructions can come either from the skid buffer or the list of
637  // instructions coming from fetch, depending on decode's status.
638  int insts_available = decodeStatus[tid] == Unblocking ?
639  skidBuffer[tid].size() : insts[tid].size();
640 
641  if (insts_available == 0) {
642  DPRINTF(Decode, "[tid:%i] Nothing to do, breaking out"
643  " early.\n",tid);
644  // Should I change the status to idle?
645  ++stats.idleCycles;
646  return;
647  } else if (decodeStatus[tid] == Unblocking) {
648  DPRINTF(Decode, "[tid:%i] Unblocking, removing insts from skid "
649  "buffer.\n",tid);
651  } else if (decodeStatus[tid] == Running) {
652  ++stats.runCycles;
653  }
654 
655  std::queue<DynInstPtr>
656  &insts_to_decode = decodeStatus[tid] == Unblocking ?
657  skidBuffer[tid] : insts[tid];
658 
659  DPRINTF(Decode, "[tid:%i] Sending instruction to rename.\n",tid);
660 
661  while (insts_available > 0 && toRenameIndex < decodeWidth) {
662  assert(!insts_to_decode.empty());
663 
664  DynInstPtr inst = std::move(insts_to_decode.front());
665 
666  insts_to_decode.pop();
667 
668  DPRINTF(Decode, "[tid:%i] Processing instruction [sn:%lli] with "
669  "PC %s\n", tid, inst->seqNum, inst->pcState());
670 
671  if (inst->isSquashed()) {
672  DPRINTF(Decode, "[tid:%i] Instruction %i with PC %s is "
673  "squashed, skipping.\n",
674  tid, inst->seqNum, inst->pcState());
675 
677 
678  --insts_available;
679 
680  continue;
681  }
682 
683  // Also check if instructions have no source registers. Mark
684  // them as ready to issue at any time. Not sure if this check
685  // should exist here or at a later stage; however it doesn't matter
686  // too much for function correctness.
687  if (inst->numSrcRegs() == 0) {
688  inst->setCanIssue();
689  }
690 
691  // This current instruction is valid, so add it into the decode
692  // queue. The next instruction may not be valid, so check to
693  // see if branches were predicted correctly.
694  toRename->insts[toRenameIndex] = inst;
695 
696  ++(toRename->size);
697  ++toRenameIndex;
699  --insts_available;
700 
701 #if TRACING_ON
702  if (DTRACE(O3PipeView)) {
703  inst->decodeTick = curTick() - inst->fetchTick;
704  }
705 #endif
706 
707  // Ensure that if it was predicted as a branch, it really is a
708  // branch.
709  if (inst->readPredTaken() && !inst->isControl()) {
710  panic("Instruction predicted as a branch!");
711 
713 
714  // Might want to set some sort of boolean and just do
715  // a check at the end
716  squash(inst, inst->threadNumber);
717 
718  break;
719  }
720 
721  // Go ahead and compute any PC-relative branches.
722  // This includes direct unconditional control and
723  // direct conditional control that is predicted taken.
724  if (inst->isDirectCtrl() &&
725  (inst->isUncondCtrl() || inst->readPredTaken()))
726  {
728 
729  if (!(inst->branchTarget() == inst->readPredTarg())) {
731 
732  // Might want to set some sort of boolean and just do
733  // a check at the end
734  squash(inst, inst->threadNumber);
735  TheISA::PCState target = inst->branchTarget();
736 
737  DPRINTF(Decode,
738  "[tid:%i] [sn:%llu] "
739  "Updating predictions: Wrong predicted target: %s \
740  PredPC: %s\n",
741  tid, inst->seqNum, inst->readPredTarg(), target);
742  //The micro pc after an instruction level branch should be 0
743  inst->setPredTarg(target);
744  break;
745  }
746  }
747  }
748 
749  // If we didn't process all instructions, then we will need to block
750  // and put all those instructions into the skid buffer.
751  if (!insts_to_decode.empty()) {
752  block(tid);
753  }
754 
755  // Record that decode has written to the time buffer for activity
756  // tracking.
757  if (toRenameIndex) {
758  wroteToTimeBuffer = true;
759  }
760 }
761 
762 #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:293
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::DefaultDecode
DefaultDecode(O3CPU *_cpu, const DerivO3CPUParams &params)
DefaultDecode constructor.
Definition: decode_impl.hh:60
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:223
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:496
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:233
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:194
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:156
FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:204
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:201
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:159
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:393
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:244
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:353
DefaultDecode::Idle
@ Idle
Definition: decode.hh:84
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
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
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
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:237
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:433
DefaultDecode::sortInsts
void sortInsts()
Separates instructions from fetch into individual lists of instructions sorted by thread.
Definition: decode_impl.hh:472
DefaultDecode::decodeInsts
void decodeInsts(ThreadID tid)
Processes instructions from fetch and passes them on to rename.
Definition: decode_impl.hh:634
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:553
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:417
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
UNIT_CYCLE
#define UNIT_CYCLE
Convenience macros to declare the unit of a stat.
Definition: units.hh:39
DefaultDecode::setFetchQueue
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Sets pointer to time buffer coming from fetch.
Definition: decode_impl.hh:184
DefaultDecode::setDecodeQueue
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
Definition: decode_impl.hh:174
Stats
Definition: statistics.cc:53
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
trace.hh
DefaultDecode::Blocked
@ Blocked
Definition: decode.hh:87
decode.hh
DefaultDecode::isDrained
bool isDrained() const
Has the stage drained?
Definition: decode_impl.hh:211
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:589
DefaultDecode::numThreads
ThreadID numThreads
number of Active Threads
Definition: decode.hh:275
std::list< ThreadID >
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:274
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
DefaultDecode::readStallSignals
void readStallSignals(ThreadID tid)
Reads all stall signals from the backwards communication timebuffer.
Definition: decode_impl.hh:482
TimeBuffer::getWire
wire getWire(int idx)
Definition: timebuf.hh:229

Generated on Tue Mar 23 2021 19:41:24 for gem5 by doxygen 1.8.17