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

Generated on Wed Dec 21 2022 10:22:30 for gem5 by doxygen 1.9.1