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

Generated on Fri Jun 9 2017 13:03:43 for gem5 by doxygen 1.8.6