gem5  v20.1.0.0
wavefront.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2017 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "gpu-compute/wavefront.hh"
35 
36 #include "debug/GPUExec.hh"
37 #include "debug/GPUInitAbi.hh"
38 #include "debug/WavefrontStack.hh"
42 #include "gpu-compute/shader.hh"
45 
46 Wavefront*
47 WavefrontParams::create()
48 {
49  return new Wavefront(this);
50 }
51 
53  : SimObject(p), wfSlotId(p->wf_slot_id), simdId(p->simdId),
54  maxIbSize(p->max_ib_size), _gpuISA(*this),
55  vmWaitCnt(-1), expWaitCnt(-1), lgkmWaitCnt(-1),
56  vmemInstsIssued(0), expInstsIssued(0), lgkmInstsIssued(0),
57  barId(WFBarrier::InvalidID)
58 {
59  lastTrace = 0;
60  execUnitId = -1;
61  status = S_STOPPED;
64  startVgprIndex = 0;
65  startSgprIndex = 0;
66  outstandingReqs = 0;
71  rdLmReqsInPipe = 0;
72  rdGmReqsInPipe = 0;
73  wrLmReqsInPipe = 0;
74  wrGmReqsInPipe = 0;
79  lastNonIdleTick = 0;
80  ldsChunk = nullptr;
81 
82  memTraceBusy = 0;
83  oldVgprTcnt = 0xffffffffffffffffll;
84  oldDgprTcnt = 0xffffffffffffffffll;
85  oldVgpr.resize(p->wf_size);
86 
87  pendingFetch = false;
88  dropFetch = false;
89  maxVgprs = 0;
90  maxSgprs = 0;
91 
92  lastAddr.resize(p->wf_size);
93  workItemFlatId.resize(p->wf_size);
94  oldDgpr.resize(p->wf_size);
95  for (int i = 0; i < 3; ++i) {
96  workItemId[i].resize(p->wf_size);
97  }
98 
99  _execMask.set();
100  rawDist.clear();
101  lastInstExec = 0;
102  vecReads.clear();
103 }
104 
105 void
107 {
109 
110  // FIXME: the name of the WF needs to be unique
112  .name(name() + ".timesBlockedDueWAXDependencies")
113  .desc("number of times the wf's instructions are blocked due to WAW "
114  "or WAR dependencies")
115  ;
116 
117  // FIXME: the name of the WF needs to be unique
119  .name(name() + ".timesBlockedDueRAWDependencies")
120  .desc("number of times the wf's instructions are blocked due to RAW "
121  "dependencies")
122  ;
123 
125  .name(name() + ".num_instr_executed")
126  .desc("number of instructions executed by this WF slot")
127  ;
128 
129  schCycles
130  .name(name() + ".sch_cycles")
131  .desc("number of cycles spent in schedule stage")
132  ;
133 
134  schStalls
135  .name(name() + ".sch_stalls")
136  .desc("number of cycles WF is stalled in SCH stage")
137  ;
138 
140  .name(name() + ".sch_rf_access_stalls")
141  .desc("number of cycles wave selected in SCH but RF denied adding "
142  "instruction")
143  ;
144 
146  .name(name() + ".sch_resource_stalls")
147  .desc("number of cycles stalled in sch by resource not available")
148  ;
149 
151  .name(name() + ".sch_opd_nrdy_stalls")
152  .desc("number of cycles stalled in sch waiting for RF reads to "
153  "complete")
154  ;
155 
157  .name(name() + ".sch_lds_arb_stalls")
158  .desc("number of cycles wave stalled due to LDS-VRF arbitration")
159  ;
160 
162  .init(0,20,1)
163  .name(name() + ".vec_raw_distance")
164  .desc("Count of RAW distance in dynamic instructions for this WF")
165  ;
166 
168  .init(0,4,1)
169  .name(name() + ".vec_reads_per_write")
170  .desc("Count of Vector reads per write for this WF")
171  ;
172 }
173 
174 void
176 {
177  reservedVectorRegs = 0;
178  reservedScalarRegs = 0;
179  startVgprIndex = 0;
180  startSgprIndex = 0;
181 
187 }
188 
189 void
190 Wavefront::initRegState(HSAQueueEntry *task, int wgSizeInWorkItems)
191 {
192  int regInitIdx = 0;
193 
194  // iterate over all the init fields and check which
195  // bits are enabled
196  for (int en_bit = 0; en_bit < NumScalarInitFields; ++en_bit) {
197 
198  if (task->sgprBitEnabled(en_bit)) {
199  int physSgprIdx = 0;
200  uint32_t wiCount = 0;
201  uint32_t firstWave = 0;
202  int orderedAppendTerm = 0;
203  int numWfsInWg = 0;
204  uint32_t finalValue = 0;
205  Addr host_disp_pkt_addr = task->hostDispPktAddr();
206  Addr kernarg_addr = task->kernargAddr();
207  Addr hidden_priv_base(0);
208 
209  switch (en_bit) {
210  case PrivateSegBuf:
211  physSgprIdx =
212  computeUnit->registerManager->mapSgpr(this, regInitIdx);
213  computeUnit->srf[simdId]->write(physSgprIdx,
215  ++regInitIdx;
216  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
217  "Setting PrivateSegBuffer: s[%d] = %x\n",
219  wfSlotId, wfDynId, physSgprIdx,
221 
222  physSgprIdx =
223  computeUnit->registerManager->mapSgpr(this, regInitIdx);
224  computeUnit->srf[simdId]->write(physSgprIdx,
226  ++regInitIdx;
227  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
228  "Setting PrivateSegBuffer: s[%d] = %x\n",
230  wfSlotId, wfDynId, physSgprIdx,
232 
233  physSgprIdx =
234  computeUnit->registerManager->mapSgpr(this, regInitIdx);
235  computeUnit->srf[simdId]->write(physSgprIdx,
237  ++regInitIdx;
238  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
239  "Setting PrivateSegBuffer: s[%d] = %x\n",
241  wfSlotId, wfDynId, physSgprIdx,
243 
244  physSgprIdx =
245  computeUnit->registerManager->mapSgpr(this, regInitIdx);
246  computeUnit->srf[simdId]->write(physSgprIdx,
248 
249  ++regInitIdx;
250  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
251  "Setting PrivateSegBuffer: s[%d] = %x\n",
253  wfSlotId, wfDynId, physSgprIdx,
255  break;
256  case DispatchPtr:
257  physSgprIdx =
258  computeUnit->registerManager->mapSgpr(this, regInitIdx);
259  computeUnit->srf[simdId]->write(physSgprIdx,
260  ((uint32_t*)&host_disp_pkt_addr)[0]);
261  ++regInitIdx;
262  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
263  "Setting DispatchPtr: s[%d] = %x\n",
265  wfSlotId, wfDynId, physSgprIdx,
266  ((uint32_t*)&host_disp_pkt_addr)[0]);
267 
268  physSgprIdx =
269  computeUnit->registerManager->mapSgpr(this, regInitIdx);
270  computeUnit->srf[simdId]->write(physSgprIdx,
271  ((uint32_t*)&host_disp_pkt_addr)[1]);
272  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
273  "Setting DispatchPtr: s[%d] = %x\n",
275  wfSlotId, wfDynId, physSgprIdx,
276  ((uint32_t*)&host_disp_pkt_addr)[1]);
277 
278  ++regInitIdx;
279  break;
280  case QueuePtr:
281  physSgprIdx =
282  computeUnit->registerManager->mapSgpr(this, regInitIdx);
283  computeUnit->srf[simdId]->write(physSgprIdx,
284  ((uint32_t*)&task->hostAMDQueueAddr)[0]);
285  ++regInitIdx;
286  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
287  "Setting QueuePtr: s[%d] = %x\n",
289  wfSlotId, wfDynId, physSgprIdx,
290  ((uint32_t*)&task->hostAMDQueueAddr)[0]);
291 
292  physSgprIdx =
293  computeUnit->registerManager->mapSgpr(this, regInitIdx);
294  computeUnit->srf[simdId]->write(physSgprIdx,
295  ((uint32_t*)&task->hostAMDQueueAddr)[1]);
296  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
297  "Setting QueuePtr: s[%d] = %x\n",
299  wfSlotId, wfDynId, physSgprIdx,
300  ((uint32_t*)&task->hostAMDQueueAddr)[1]);
301 
302  ++regInitIdx;
303  break;
304  case KernargSegPtr:
305  physSgprIdx =
306  computeUnit->registerManager->mapSgpr(this, regInitIdx);
307  computeUnit->srf[simdId]->write(physSgprIdx,
308  ((uint32_t*)&kernarg_addr)[0]);
309  ++regInitIdx;
310  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
311  "Setting KernargSegPtr: s[%d] = %x\n",
313  wfSlotId, wfDynId, physSgprIdx,
314  ((uint32_t*)kernarg_addr)[0]);
315 
316  physSgprIdx =
317  computeUnit->registerManager->mapSgpr(this, regInitIdx);
318  computeUnit->srf[simdId]->write(physSgprIdx,
319  ((uint32_t*)&kernarg_addr)[1]);
320  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
321  "Setting KernargSegPtr: s[%d] = %x\n",
323  wfSlotId, wfDynId, physSgprIdx,
324  ((uint32_t*)kernarg_addr)[1]);
325 
326  ++regInitIdx;
327  break;
328  case FlatScratchInit:
329  physSgprIdx
330  = computeUnit->registerManager->mapSgpr(this, regInitIdx);
331  computeUnit->srf[simdId]->write(physSgprIdx,
333  .scratch_backing_memory_location & 0xffffffff));
334  ++regInitIdx;
335  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
336  "Setting FlatScratch Addr: s[%d] = %x\n",
338  wfSlotId, wfDynId, physSgprIdx,
340  .scratch_backing_memory_location & 0xffffffff));
341 
342  physSgprIdx =
343  computeUnit->registerManager->mapSgpr(this, regInitIdx);
344  // This vallue should be sizeof(DWORD) aligned, that is
345  // 4 byte aligned
346  computeUnit->srf[simdId]->write(physSgprIdx,
348  ++regInitIdx;
349  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
350  "Setting FlatScratch size: s[%d] = %x\n",
352  wfSlotId, wfDynId, physSgprIdx,
377  hidden_priv_base =
378  (uint64_t)task->amdQueue.scratch_resource_descriptor[0] |
379  (((uint64_t)task->amdQueue.scratch_resource_descriptor[1]
380  & 0x000000000000ffff) << 32);
382  hidden_priv_base,
384  break;
385  case GridWorkgroupCountX:
386  physSgprIdx =
387  computeUnit->registerManager->mapSgpr(this, regInitIdx);
388  wiCount = ((task->gridSize(0) +
389  task->wgSize(0) - 1) /
390  task->wgSize(0));
391  computeUnit->srf[simdId]->write(physSgprIdx, wiCount);
392 
393  ++regInitIdx;
394  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
395  "Setting num WG X: s[%d] = %x\n",
397  wfSlotId, wfDynId, physSgprIdx, wiCount);
398  break;
399  case GridWorkgroupCountY:
400  physSgprIdx =
401  computeUnit->registerManager->mapSgpr(this, regInitIdx);
402  wiCount = ((task->gridSize(1) +
403  task->wgSize(1) - 1) /
404  task->wgSize(1));
405  computeUnit->srf[simdId]->write(physSgprIdx, wiCount);
406 
407  ++regInitIdx;
408  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
409  "Setting num WG Y: s[%d] = %x\n",
411  wfSlotId, wfDynId, physSgprIdx, wiCount);
412  break;
413  case GridWorkgroupCountZ:
414  physSgprIdx =
415  computeUnit->registerManager->mapSgpr(this, regInitIdx);
416  wiCount = ((task->gridSize(2) +
417  task->wgSize(2) - 1) /
418  task->wgSize(2));
419  computeUnit->srf[simdId]->write(physSgprIdx, wiCount);
420 
421  ++regInitIdx;
422  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
423  "Setting num WG Z: s[%d] = %x\n",
425  wfSlotId, wfDynId, physSgprIdx, wiCount);
426  break;
427  case WorkgroupIdX:
428  physSgprIdx =
429  computeUnit->registerManager->mapSgpr(this, regInitIdx);
430  computeUnit->srf[simdId]->write(physSgprIdx,
431  workGroupId[0]);
432 
433  ++regInitIdx;
434  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
435  "Setting WG ID X: s[%d] = %x\n",
437  wfSlotId, wfDynId, physSgprIdx, workGroupId[0]);
438  break;
439  case WorkgroupIdY:
440  physSgprIdx =
441  computeUnit->registerManager->mapSgpr(this, regInitIdx);
442  computeUnit->srf[simdId]->write(physSgprIdx,
443  workGroupId[1]);
444 
445  ++regInitIdx;
446  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
447  "Setting WG ID Y: s[%d] = %x\n",
449  wfSlotId, wfDynId, physSgprIdx, workGroupId[1]);
450  break;
451  case WorkgroupIdZ:
452  physSgprIdx =
453  computeUnit->registerManager->mapSgpr(this, regInitIdx);
454  computeUnit->srf[simdId]->write(physSgprIdx,
455  workGroupId[2]);
456 
457  ++regInitIdx;
458  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
459  "Setting WG ID Z: s[%d] = %x\n",
461  wfSlotId, wfDynId, physSgprIdx, workGroupId[2]);
462  break;
464  physSgprIdx =
465  computeUnit->registerManager->mapSgpr(this, regInitIdx);
479  computeUnit->srf[simdId]->write(physSgprIdx, 1024 *
480  (wgId * (wgSz / 64) + wfId) *
482 
483  ++regInitIdx;
484  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
485  "Setting Private Seg Offset: s[%d] = %x\n",
487  wfSlotId, wfDynId, physSgprIdx,
488  1024 * (wgId * (wgSz / 64) + wfId) *
490  break;
491  case WorkgroupInfo:
492  firstWave = (wfId == 0) ? 1 : 0;
493  numWfsInWg = divCeil(wgSizeInWorkItems,
494  computeUnit->wfSize());
495  finalValue = firstWave << ((sizeof(uint32_t) * 8) - 1);
496  finalValue |= (orderedAppendTerm << 6);
497  finalValue |= numWfsInWg;
498  physSgprIdx =
499  computeUnit->registerManager->mapSgpr(this, regInitIdx);
501  write(physSgprIdx, finalValue);
502 
503  ++regInitIdx;
504  DPRINTF(GPUInitAbi, "CU%d: WF[%d][%d]: wave[%d] "
505  "Setting WG Info: s[%d] = %x\n",
507  wfSlotId, wfDynId, physSgprIdx, finalValue);
508  break;
509  default:
510  fatal("SGPR enable bit %i not supported\n", en_bit);
511  break;
512  }
513  }
514  }
515 
516  regInitIdx = 0;
517 
518  // iterate over all the init fields and check which
519  // bits are enabled
520  for (int en_bit = 0; en_bit < NumVectorInitFields; ++en_bit) {
521  if (task->vgprBitEnabled(en_bit)) {
522  uint32_t physVgprIdx = 0;
524 
525  switch (en_bit) {
526  case WorkitemIdX:
527  {
528  physVgprIdx = computeUnit->registerManager
529  ->mapVgpr(this, regInitIdx);
530  TheGpuISA::VecRegU32 vgpr_x
531  = raw_vgpr.as<TheGpuISA::VecElemU32>();
532 
533  for (int lane = 0; lane < workItemId[0].size(); ++lane) {
534  vgpr_x[lane] = workItemId[0][lane];
535  }
536 
537  computeUnit->vrf[simdId]->write(physVgprIdx, raw_vgpr);
538  rawDist[regInitIdx] = 0;
539  ++regInitIdx;
540  }
541  break;
542  case WorkitemIdY:
543  {
544  physVgprIdx = computeUnit->registerManager
545  ->mapVgpr(this, regInitIdx);
546  TheGpuISA::VecRegU32 vgpr_y
547  = raw_vgpr.as<TheGpuISA::VecElemU32>();
548 
549  for (int lane = 0; lane < workItemId[1].size(); ++lane) {
550  vgpr_y[lane] = workItemId[1][lane];
551  }
552 
553  computeUnit->vrf[simdId]->write(physVgprIdx, raw_vgpr);
554  rawDist[regInitIdx] = 0;
555  ++regInitIdx;
556  }
557  break;
558  case WorkitemIdZ:
559  {
560  physVgprIdx = computeUnit->registerManager->
561  mapVgpr(this, regInitIdx);
562  TheGpuISA::VecRegU32 vgpr_z
563  = raw_vgpr.as<TheGpuISA::VecElemU32>();
564 
565  for (int lane = 0; lane < workItemId[2].size(); ++lane) {
566  vgpr_z[lane] = workItemId[2][lane];
567  }
568 
569  computeUnit->vrf[simdId]->write(physVgprIdx, raw_vgpr);
570  rawDist[regInitIdx] = 0;
571  ++regInitIdx;
572  }
573  break;
574  }
575  }
576  }
577 }
578 
579 void
580 Wavefront::resizeRegFiles(int num_vregs, int num_sregs)
581 {
582  maxVgprs = num_vregs;
583  maxSgprs = num_sregs;
584 }
585 
587 {
588 }
589 
590 void
592 {
593  if (computeUnit->idleCUTimeout > 0) {
594  // Wavefront's status transitions to stalled or stopped
595  if ((newStatus == S_STOPPED || newStatus == S_STALLED ||
596  newStatus == S_WAITCNT || newStatus == S_BARRIER) &&
597  (status != newStatus)) {
598  computeUnit->idleWfs++;
599  assert(computeUnit->idleWfs <=
601  if (computeUnit->idleWfs ==
604  }
605  // Wavefront's status transitions to an active state (from
606  // a stopped or stalled state)
607  } else if ((status == S_STOPPED || status == S_STALLED ||
608  status == S_WAITCNT || status == S_BARRIER) &&
609  (status != newStatus)) {
610  // if all WFs in the CU were idle then check if the idleness
611  // period exceeded the timeout threshold
612  if (computeUnit->idleWfs ==
616  "CU%d has been idle for %d ticks at tick %d",
618  curTick());
619  }
620  computeUnit->idleWfs--;
621  assert(computeUnit->idleWfs >= 0);
622  }
623  }
624  status = newStatus;
625 }
626 
627 void
628 Wavefront::start(uint64_t _wf_dyn_id, Addr init_pc)
629 {
630  wfDynId = _wf_dyn_id;
631  _pc = init_pc;
632 
633  status = S_RUNNING;
634 
635  vecReads.resize(maxVgprs, 0);
636 }
637 
638 bool
640 {
641  if (ii->isGlobalMem() ||
642  (ii->isFlat() && ii->executedAs() == Enums::SC_GLOBAL)) {
643  return true;
644  }
645 
646  return false;
647 }
648 
649 bool
651 {
652  if (ii->isLocalMem() ||
653  (ii->isFlat() && ii->executedAs() == Enums::SC_GROUP)) {
654  return true;
655  }
656 
657  return false;
658 }
659 
660 bool
662 {
663  if (instructionBuffer.empty())
664  return false;
665 
666  GPUDynInstPtr ii = instructionBuffer.front();
667 
668  if (ii->isWaitcnt()) {
669  // waitcnt is a scalar
670  assert(ii->isScalar());
671  return true;
672  }
673 
674  return false;
675 }
676 
677 bool
679 {
680  assert(!instructionBuffer.empty());
681  GPUDynInstPtr ii = instructionBuffer.front();
682 
683  if (status != S_STOPPED && ii->isScalar() && (ii->isNop() || ii->isReturn()
684  || ii->isEndOfKernel() || ii->isBranch() || ii->isALU() ||
685  (ii->isKernArgSeg() && ii->isLoad()))) {
686  return true;
687  }
688 
689  return false;
690 }
691 
692 bool
694 {
695  assert(!instructionBuffer.empty());
696  GPUDynInstPtr ii = instructionBuffer.front();
697 
698  if (status != S_STOPPED && !ii->isScalar() && (ii->isNop() ||
699  ii->isReturn() || ii->isBranch() || ii->isALU() || ii->isEndOfKernel()
700  || (ii->isKernArgSeg() && ii->isLoad()))) {
701  return true;
702  }
703 
704  return false;
705 }
706 
707 bool
709 {
710  assert(!instructionBuffer.empty());
711  GPUDynInstPtr ii = instructionBuffer.front();
712 
713  if (status != S_STOPPED && ii->isBarrier()) {
714  return true;
715  }
716 
717  return false;
718 }
719 
720 bool
722 {
723  assert(!instructionBuffer.empty());
724  GPUDynInstPtr ii = instructionBuffer.front();
725 
726  if (status != S_STOPPED && !ii->isScalar() && ii->isGlobalMem()) {
727  return true;
728  }
729 
730  return false;
731 }
732 
733 bool
735 {
736  assert(!instructionBuffer.empty());
737  GPUDynInstPtr ii = instructionBuffer.front();
738 
739  if (status != S_STOPPED && ii->isScalar() && ii->isGlobalMem()) {
740  return true;
741  }
742 
743  return false;
744 }
745 
746 bool
748 {
749  assert(!instructionBuffer.empty());
750  GPUDynInstPtr ii = instructionBuffer.front();
751 
752  if (status != S_STOPPED && ii->isLocalMem()) {
753  return true;
754  }
755 
756  return false;
757 }
758 
759 bool
761 {
762  assert(!instructionBuffer.empty());
763  GPUDynInstPtr ii = instructionBuffer.front();
764 
765  if (status != S_STOPPED && ii->isPrivateSeg()) {
766  return true;
767  }
768 
769  return false;
770 }
771 
772 bool
774 {
775  assert(!instructionBuffer.empty());
776  GPUDynInstPtr ii = instructionBuffer.front();
777 
778  if (status != S_STOPPED && ii->isFlat()) {
779  return true;
780  }
781 
782  return false;
783 }
784 
785 bool
787 {
788  for (auto it : instructionBuffer) {
789  GPUDynInstPtr ii = it;
790  if (ii->isReturn() || ii->isBranch() ||
791  ii->isEndOfKernel()) {
792  return true;
793  }
794  }
795 
796  return false;
797 }
798 
799 void
801 {
802  execUnitId = -1;
803 }
804 
806 {
808  wrLmReqsInPipe < 0 || rdLmReqsInPipe < 0 ||
809  outstandingReqs < 0,
810  "Negative requests in pipe for WF%d for slot%d"
811  " and SIMD%d: Rd GlobalMem Reqs=%d, Wr GlobalMem Reqs=%d,"
812  " Rd LocalMem Reqs=%d, Wr LocalMem Reqs=%d,"
813  " Outstanding Reqs=%d\n",
816 }
817 
818 void
820 {
821  if (!ii->isScalar()) {
822  if (ii->isLoad()) {
823  rdGmReqsInPipe++;
824  } else if (ii->isStore()) {
825  wrGmReqsInPipe++;
826  } else if (ii->isAtomic() || ii->isMemSync()) {
827  rdGmReqsInPipe++;
828  wrGmReqsInPipe++;
829  } else {
830  panic("Invalid memory operation!\n");
831  }
833  } else {
834  if (ii->isLoad()) {
836  } else if (ii->isStore()) {
838  } else if (ii->isAtomic() || ii->isMemSync()) {
841  } else {
842  panic("Invalid memory operation!\n");
843  }
845  }
846 }
847 
848 void
850 {
851  fatal_if(ii->isScalar(),
852  "Scalar instructions can not access Shared memory!!!");
853  if (ii->isLoad()) {
854  rdLmReqsInPipe++;
855  } else if (ii->isStore()) {
856  wrLmReqsInPipe++;
857  } else if (ii->isAtomic() || ii->isMemSync()) {
858  wrLmReqsInPipe++;
859  rdLmReqsInPipe++;
860  } else {
861  panic("Invalid memory operation!\n");
862  }
864 }
865 
868 {
869  // vector of execution unit IDs to return to schedule stage
870  // this return is only used for debugging and an assertion...
871  std::vector<int> execUnitIds;
872 
873  // Get current instruction
874  GPUDynInstPtr ii = instructionBuffer.front();
875  assert(ii);
876 
877  // Single precision ALU or Branch or Return or Special instruction
878  if (ii->isALU() || ii->isSpecialOp() ||
879  ii->isBranch() || ii->isNop() ||
880  (ii->isKernArgSeg() && ii->isLoad()) || ii->isArgSeg() ||
881  ii->isReturn() || ii->isEndOfKernel()) {
882  if (!ii->isScalar()) {
883  execUnitId = simdId;
884  } else {
886  }
887  // this is to enforce a fixed number of cycles per issue slot per SIMD
888  } else if (ii->isBarrier()) {
889  execUnitId = ii->isScalar() ? scalarAluGlobalIdx : simdId;
890  } else if (ii->isFlat()) {
891  assert(!ii->isScalar());
892  reserveLmResource(ii);
893  // add execUnitId, reserved by reserveLmResource, list before it is
894  // overwriten by reserveGmResource
895  execUnitIds.push_back(execUnitId);
897  reserveGmResource(ii);
899  execUnitIds.push_back(flatGmUnitId);
900  execUnitId = -1;
901  } else if (ii->isGlobalMem()) {
902  reserveGmResource(ii);
903  } else if (ii->isLocalMem()) {
904  reserveLmResource(ii);
905  } else if (ii->isPrivateSeg()) {
906  fatal_if(ii->isScalar(),
907  "Scalar instructions can not access Private memory!!!");
908  reserveGmResource(ii);
909  } else {
910  panic("reserveResources -> Couldn't process op!\n");
911  }
912 
913  if (execUnitId != -1) {
914  execUnitIds.push_back(execUnitId);
915  }
916  assert(execUnitIds.size());
917  return execUnitIds;
918 }
919 
920 void
922 {
923  // ---- Exit if wavefront is inactive ----------------------------- //
924 
925  if (status == S_STOPPED || status == S_RETURNING ||
926  status==S_STALLED || instructionBuffer.empty()) {
927  return;
928  }
929 
930  if (status == S_WAITCNT) {
942  assert(isOldestInstWaitcnt());
943  }
944 
945  // Get current instruction
946 
947  GPUDynInstPtr ii = instructionBuffer.front();
948 
949  const Addr old_pc = pc();
950  DPRINTF(GPUExec, "CU%d: WF[%d][%d]: wave[%d] Executing inst: %s "
951  "(pc: %#x; seqNum: %d)\n", computeUnit->cu_id, simdId, wfSlotId,
952  wfDynId, ii->disassemble(), old_pc, ii->seqNum());
953 
954  ii->execute(ii);
955  // delete the dynamic instruction from the pipeline map
957  // update the instruction stats in the CU
959 
960  // inform VRF of instruction execution to schedule write-back
961  // and scoreboard ready for registers
962  if (!ii->isScalar()) {
963  computeUnit->vrf[simdId]->waveExecuteInst(this, ii);
964  }
965  computeUnit->srf[simdId]->waveExecuteInst(this, ii);
966 
967  computeUnit->shader->vectorInstSrcOperand[ii->numSrcVecOperands()]++;
968  computeUnit->shader->vectorInstDstOperand[ii->numDstVecOperands()]++;
975 
976  if (lastInstExec) {
979  }
981 
982  // want to track:
983  // number of reads that occur per value written
984 
985  // vector RAW dependency tracking
986  for (int i = 0; i < ii->getNumOperands(); i++) {
987  if (ii->isVectorRegister(i)) {
988  int vgpr = ii->getRegisterIndex(i, ii);
989  int nReg = ii->getOperandSize(i) <= 4 ? 1 :
990  ii->getOperandSize(i) / 4;
991  for (int n = 0; n < nReg; n++) {
992  if (ii->isSrcOperand(i)) {
993  // This check should never fail, but to be safe we check
994  if (rawDist.find(vgpr+n) != rawDist.end()) {
996  sample(numInstrExecuted.value() - rawDist[vgpr+n]);
997  }
998  // increment number of reads to this register
999  vecReads[vgpr+n]++;
1000  } else if (ii->isDstOperand(i)) {
1001  // rawDist is set on writes, but will not be set
1002  // for the first write to each physical register
1003  if (rawDist.find(vgpr+n) != rawDist.end()) {
1004  // sample the number of reads that were performed
1005  readsPerWrite.sample(vecReads[vgpr+n]);
1006  }
1007  // on a write, reset count of reads to 0
1008  vecReads[vgpr+n] = 0;
1009 
1010  rawDist[vgpr+n] = numInstrExecuted.value();
1011  }
1012  }
1013  }
1014  }
1015 
1016  if (pc() == old_pc) {
1017  // PC not modified by instruction, proceed to next
1018  _gpuISA.advancePC(ii);
1019  instructionBuffer.pop_front();
1020  } else {
1021  DPRINTF(GPUExec, "CU%d: WF[%d][%d]: wave%d %s taken branch\n",
1023  ii->disassemble());
1024  discardFetch();
1025  }
1026  DPRINTF(GPUExec, "CU%d: WF[%d][%d]: wave[%d] (pc: %#x)\n",
1028 
1030  const int num_active_lanes = execMask().count();
1031  computeUnit->controlFlowDivergenceDist.sample(num_active_lanes);
1032  computeUnit->numVecOpsExecuted += num_active_lanes;
1033 
1034  if (ii->isF16() && ii->isALU()) {
1035  if (ii->isF32() || ii->isF64()) {
1036  fatal("Instruction is tagged as both (1) F16, and (2)"
1037  "either F32 or F64.");
1038  }
1039  computeUnit->numVecOpsExecutedF16 += num_active_lanes;
1040  if (ii->isFMA()) {
1041  computeUnit->numVecOpsExecutedFMA16 += num_active_lanes;
1042  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1043  }
1044  else if (ii->isMAC()) {
1045  computeUnit->numVecOpsExecutedMAC16 += num_active_lanes;
1046  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1047  }
1048  else if (ii->isMAD()) {
1049  computeUnit->numVecOpsExecutedMAD16 += num_active_lanes;
1050  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1051  }
1052  }
1053  if (ii->isF32() && ii->isALU()) {
1054  if (ii->isF16() || ii->isF64()) {
1055  fatal("Instruction is tagged as both (1) F32, and (2)"
1056  "either F16 or F64.");
1057  }
1058  computeUnit->numVecOpsExecutedF32 += num_active_lanes;
1059  if (ii->isFMA()) {
1060  computeUnit->numVecOpsExecutedFMA32 += num_active_lanes;
1061  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1062  }
1063  else if (ii->isMAC()) {
1064  computeUnit->numVecOpsExecutedMAC32 += num_active_lanes;
1065  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1066  }
1067  else if (ii->isMAD()) {
1068  computeUnit->numVecOpsExecutedMAD32 += num_active_lanes;
1069  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1070  }
1071  }
1072  if (ii->isF64() && ii->isALU()) {
1073  if (ii->isF16() || ii->isF32()) {
1074  fatal("Instruction is tagged as both (1) F64, and (2)"
1075  "either F16 or F32.");
1076  }
1077  computeUnit->numVecOpsExecutedF64 += num_active_lanes;
1078  if (ii->isFMA()) {
1079  computeUnit->numVecOpsExecutedFMA64 += num_active_lanes;
1080  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1081  }
1082  else if (ii->isMAC()) {
1083  computeUnit->numVecOpsExecutedMAC64 += num_active_lanes;
1084  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1085  }
1086  else if (ii->isMAD()) {
1087  computeUnit->numVecOpsExecutedMAD64 += num_active_lanes;
1088  computeUnit->numVecOpsExecutedTwoOpFP += num_active_lanes;
1089  }
1090  }
1091  if (isGmInstruction(ii)) {
1092  computeUnit->activeLanesPerGMemInstrDist.sample(num_active_lanes);
1093  } else if (isLmInstruction(ii)) {
1094  computeUnit->activeLanesPerLMemInstrDist.sample(num_active_lanes);
1095  }
1096  }
1097 
1102  if (execMask().none() && ii->isFlat()) {
1104  return;
1105  }
1106 
1107  // Update Vector ALU pipeline and other resources
1108  bool flat_as_gm = false;
1109  bool flat_as_lm = false;
1110  if (ii->isFlat()) {
1111  flat_as_gm = (ii->executedAs() == Enums::SC_GLOBAL) ||
1112  (ii->executedAs() == Enums::SC_PRIVATE);
1113  flat_as_lm = (ii->executedAs() == Enums::SC_GROUP);
1114  }
1115 
1116  // Single precision ALU or Branch or Return or Special instruction
1117  // Note, we use the same timing regardless of SP or DP ALU operation.
1118  if (ii->isALU() || ii->isSpecialOp() ||
1119  ii->isBranch() || ii->isNop() ||
1120  (ii->isKernArgSeg() && ii->isLoad()) ||
1121  ii->isArgSeg() || ii->isEndOfKernel() || ii->isReturn()) {
1122  // this is to enforce a fixed number of cycles per issue slot per SIMD
1123  if (!ii->isScalar()) {
1125  cyclesToTicks(computeUnit->issuePeriod));
1126  } else {
1128  cyclesToTicks(computeUnit->issuePeriod));
1129  }
1130  // Barrier on Scalar ALU
1131  } else if (ii->isBarrier()) {
1133  cyclesToTicks(computeUnit->issuePeriod));
1134  // GM or Flat as GM Load
1135  } else if (ii->isLoad() && (ii->isGlobalMem() || flat_as_gm)) {
1136  if (!ii->isScalar()) {
1143  } else {
1145  cyclesToTicks(computeUnit->srf_scm_bus_latency));
1150  }
1151  // GM or Flat as GM Store
1152  } else if (ii->isStore() && (ii->isGlobalMem() || flat_as_gm)) {
1153  if (!ii->isScalar()) {
1155  cyclesToTicks(Cycles(2 * computeUnit->vrf_gm_bus_latency)));
1160  } else {
1162  cyclesToTicks(Cycles(2 * computeUnit->srf_scm_bus_latency)));
1167  }
1168  } else if ((ii->isAtomic() || ii->isMemSync()) &&
1169  (ii->isGlobalMem() || flat_as_gm)) {
1170  if (!ii->isScalar()) {
1172  cyclesToTicks(Cycles(2 * computeUnit->vrf_gm_bus_latency)));
1177  } else {
1179  cyclesToTicks(Cycles(2 * computeUnit->srf_scm_bus_latency)));
1184  }
1185  // LM or Flat as LM Load
1186  } else if (ii->isLoad() && (ii->isLocalMem() || flat_as_lm)) {
1188  cyclesToTicks(computeUnit->vrf_lm_bus_latency));
1193  // LM or Flat as LM Store
1194  } else if (ii->isStore() && (ii->isLocalMem() || flat_as_lm)) {
1196  cyclesToTicks(Cycles(2 * computeUnit->vrf_lm_bus_latency)));
1201  // LM or Flat as LM, Atomic or MemFence
1202  } else if ((ii->isAtomic() || ii->isMemSync()) &&
1203  (ii->isLocalMem() || flat_as_lm)) {
1205  cyclesToTicks(Cycles(2 * computeUnit->vrf_lm_bus_latency)));
1210  } else {
1211  panic("Bad instruction type!\n");
1212  }
1213 }
1214 
1217 {
1218  // Read next instruction from instruction buffer
1219  GPUDynInstPtr ii = instructionBuffer.front();
1220  // if the WF has been dispatched in the schedule stage then
1221  // check the next oldest instruction for readiness
1222  if (computeUnit->pipeMap.find(ii->seqNum()) !=
1223  computeUnit->pipeMap.end()) {
1224  if (instructionBuffer.size() > 1) {
1225  auto it = instructionBuffer.begin() + 1;
1226  return *it;
1227  } else { // No new instructions to check
1228  return nullptr;
1229  }
1230  }
1231  return ii;
1232 }
1233 
1234 void
1236 {
1237  instructionBuffer.clear();
1239 
1245 }
1246 
1247 bool
1249 {
1250  // Both vmWaitCnt && lgkmWaitCnt uninitialized means
1251  // waitCnt instruction has been dispatched but not executed yet: next
1252  // instruction should be blocked until waitCnt is executed.
1253  if (vmWaitCnt == -1 && expWaitCnt == -1 && lgkmWaitCnt == -1) {
1254  return false;
1255  }
1256 
1262  if (vmWaitCnt != -1) {
1263  if (vmemInstsIssued > vmWaitCnt) {
1264  // vmWaitCnt not satisfied
1265  return false;
1266  }
1267  }
1268 
1269  if (expWaitCnt != -1) {
1270  if (expInstsIssued > expWaitCnt) {
1271  // expWaitCnt not satisfied
1272  return false;
1273  }
1274  }
1275 
1276  if (lgkmWaitCnt != -1) {
1277  if (lgkmInstsIssued > lgkmWaitCnt) {
1278  // lgkmWaitCnt not satisfied
1279  return false;
1280  }
1281  }
1282 
1283  // if we get here all outstanding waitcnts must
1284  // be satisfied, so we resume normal operation
1285  clearWaitCnts();
1286 
1287  return true;
1288 }
1289 
1290 void
1291 Wavefront::setWaitCnts(int vm_wait_cnt, int exp_wait_cnt, int lgkm_wait_cnt)
1292 {
1293  // the scoreboard should have set the status
1294  // to S_WAITCNT once a waitcnt instruction
1295  // was marked as ready
1296  assert(status == S_WAITCNT);
1297 
1298  // waitcnt instruction shouldn't be sending
1299  // negative counts
1300  assert(vm_wait_cnt >= 0);
1301  assert(exp_wait_cnt >= 0);
1302  assert(lgkm_wait_cnt >= 0);
1303  // waitcnts are a max of 15 because we have
1304  // only 1 nibble (4 bits) to set the counts
1305  assert(vm_wait_cnt <= 0xf);
1306  assert(exp_wait_cnt <= 0x7);
1307  assert(lgkm_wait_cnt <= 0x1f);
1308 
1315  assert(vmWaitCnt == -1);
1316  assert(expWaitCnt == -1);
1317  assert(lgkmWaitCnt == -1);
1318 
1325  if (vm_wait_cnt != 0xf)
1326  vmWaitCnt = vm_wait_cnt;
1327 
1328  if (exp_wait_cnt != 0x7)
1329  expWaitCnt = exp_wait_cnt;
1330 
1331  if (lgkm_wait_cnt != 0x1f)
1332  lgkmWaitCnt = lgkm_wait_cnt;
1333 }
1334 
1335 void
1337 {
1338  // reset the waitcnts back to
1339  // -1, indicating they are no
1340  // longer valid
1341  vmWaitCnt = -1;
1342  expWaitCnt = -1;
1343  lgkmWaitCnt = -1;
1344 
1345  // resume running normally
1346  status = S_RUNNING;
1347 }
1348 
1349 void
1351 {
1352  ++vmemInstsIssued;
1353 }
1354 
1355 void
1357 {
1358  ++expInstsIssued;
1359 }
1360 
1361 void
1363 {
1364  ++lgkmInstsIssued;
1365 }
1366 
1367 void
1369 {
1370  --vmemInstsIssued;
1371 }
1372 
1373 void
1375 {
1376  --expInstsIssued;
1377 }
1378 
1379 void
1381 {
1382  --lgkmInstsIssued;
1383 }
1384 
1385 Addr
1387 {
1388  return _pc;
1389 }
1390 
1391 void
1393 {
1394  _pc = new_pc;
1395 }
1396 
1397 VectorMask&
1399 {
1400  return _execMask;
1401 }
1402 
1403 bool
1404 Wavefront::execMask(int lane) const
1405 {
1406  return _execMask[lane];
1407 }
1408 
1409 void
1411 {
1412  /* clear busy registers */
1413  for (int i=0; i < maxVgprs; i++) {
1414  int vgprIdx = computeUnit->registerManager->mapVgpr(this, i);
1415  computeUnit->vrf[simdId]->markReg(vgprIdx, false);
1416  }
1417 
1418  /* Free registers used by this wavefront */
1419  uint32_t endIndex = (startVgprIndex + reservedVectorRegs - 1) %
1420  computeUnit->vrf[simdId]->numRegs();
1422  freeRegion(startVgprIndex, endIndex);
1423 }
1424 
1425 void
1427 {
1428  actualWgSzTotal = 1;
1429  for (int d = 0; d < HSAQueueEntry::MAX_DIM; ++d) {
1430  actualWgSz[d] = std::min(workGroupSz[d], gridSz[d]
1431  - task->wgId(d) * workGroupSz[d]);
1433  }
1434 }
1435 
1436 void
1438 {
1439  assert(bar_id >= WFBarrier::InvalidID);
1440  assert(bar_id < computeUnit->numBarrierSlots());
1441  barId = bar_id;
1442 }
1443 
1444 int
1446 {
1447  return barId;
1448 }
1449 
1450 bool
1452 {
1453  return barId > WFBarrier::InvalidID;
1454 }
1455 
1456 void
1458 {
1460 }
ComputeUnit::controlFlowDivergenceDist
Stats::Distribution controlFlowDivergenceDist
Definition: compute_unit.hh:593
ComputeUnit::vectorALUs
std::vector< WaitClass > vectorALUs
Definition: compute_unit.hh:242
Wavefront::isOldestInstScalarALU
bool isOldestInstScalarALU()
Definition: wavefront.cc:678
WorkgroupIdX
@ WorkgroupIdX
Definition: kernel_code.hh:67
_amd_queue_s::scratch_resource_descriptor
uint32_t scratch_resource_descriptor[4]
Definition: hsa_queue.hh:82
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
ComputeUnit::vectorSharedMemUnit
WaitClass vectorSharedMemUnit
Definition: compute_unit.hh:230
PrivSegWaveByteOffset
@ PrivSegWaveByteOffset
Definition: kernel_code.hh:71
Wavefront::barId
int barId
Definition: wavefront.hh:359
Wavefront::isOldestInstFlatMem
bool isOldestInstFlatMem()
Definition: wavefront.cc:773
Stats::Group::regStats
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:64
Shader::vectorInstDstOperand
Stats::Vector vectorInstDstOperand
Definition: shader.hh:257
Wavefront::schCycles
Stats::Scalar schCycles
Definition: wavefront.hh:227
Wavefront::wrGmReqsInPipe
int wrGmReqsInPipe
Definition: wavefront.hh:179
TokenManager::recvTokens
void recvTokens(int num_tokens)
Increment the number of available tokens by num_tokens.
Definition: token_port.cc:156
Wavefront::clearWaitCnts
void clearWaitCnts()
Definition: wavefront.cc:1336
Wavefront::schStalls
Stats::Scalar schStalls
Definition: wavefront.hh:230
Wavefront::lgkmInstsIssued
int lgkmInstsIssued
Definition: wavefront.hh:355
Wavefront::scalarMem
int scalarMem
Definition: wavefront.hh:121
simple_pool_manager.hh
Wavefront::startVgprIndex
uint32_t startVgprIndex
Definition: wavefront.hh:191
ComputeUnit::deleteFromPipeMap
void deleteFromPipeMap(Wavefront *w)
Definition: compute_unit.cc:491
ComputeUnit::numInstrExecuted
Stats::Scalar numInstrExecuted
Definition: compute_unit.hh:560
Wavefront::barrierId
int barrierId() const
Definition: wavefront.cc:1445
ComputeUnit::vrfToGlobalMemPipeBus
WaitClass vrfToGlobalMemPipeBus
Definition: compute_unit.hh:220
ComputeUnit::mapWaveToScalarAluGlobalIdx
int mapWaveToScalarAluGlobalIdx(Wavefront *w) const
Definition: compute_unit.cc:261
_amd_queue_s::scratch_workitem_byte_size
uint32_t scratch_workitem_byte_size
Definition: hsa_queue.hh:85
HSAQueueEntry::hostDispPktAddr
Addr hostDispPktAddr() const
Definition: hsa_queue_entry.hh:166
shader.hh
ComputeUnit::numVecOpsExecutedF16
Stats::Scalar numVecOpsExecutedF16
Definition: compute_unit.hh:567
PrivateSegBuf
@ PrivateSegBuf
Definition: kernel_code.hh:57
HSAQueueEntry::MAX_DIM
const static int MAX_DIM
Definition: hsa_queue_entry.hh:311
Wavefront::resizeRegFiles
void resizeRegFiles(int num_vregs, int num_sregs)
Definition: wavefront.cc:580
Wavefront::vecReads
std::vector< int > vecReads
Definition: wavefront.hh:268
HSAQueueEntry::vgprBitEnabled
bool vgprBitEnabled(int bit) const
Definition: hsa_queue_entry.hh:287
Wavefront::oldVgprTcnt
uint64_t oldVgprTcnt
Definition: wavefront.hh:201
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
Wavefront::globalMem
int globalMem
Definition: wavefront.hh:119
ComputeUnit::mapWaveToGlobalMem
int mapWaveToGlobalMem(Wavefront *w) const
Definition: compute_unit.cc:268
Gcn3ISA::VecRegU32
::VecRegT< VecElemU32, NumVecElemPerVecReg, false > VecRegU32
Definition: registers.hh:178
ComputeUnit::srf_scm_bus_latency
Cycles srf_scm_bus_latency
Definition: compute_unit.hh:315
ComputeUnit::instCyclesLdsPerSimd
Stats::Vector instCyclesLdsPerSimd
Definition: compute_unit.hh:506
Wavefront::_execMask
VectorMask _execMask
Definition: wavefront.hh:358
Shader::initShHiddenPrivateBase
void initShHiddenPrivateBase(Addr queueBase, uint32_t offset)
Definition: shader.hh:192
ComputeUnit::vrf_gm_bus_latency
Cycles vrf_gm_bus_latency
Definition: compute_unit.hh:313
Wavefront::oldVgpr
std::vector< uint32_t > oldVgpr
Definition: wavefront.hh:197
ComputeUnit::mapWaveToScalarMem
int mapWaveToScalarMem(Wavefront *w) const
Definition: compute_unit.cc:284
Wavefront::vmemInstsIssued
int vmemInstsIssued
Definition: wavefront.hh:353
ComputeUnit::mapWaveToLocalMem
int mapWaveToLocalMem(Wavefront *w) const
Definition: compute_unit.cc:276
Wavefront::schOpdNrdyStalls
Stats::Scalar schOpdNrdyStalls
Definition: wavefront.hh:240
Wavefront::S_RUNNING
@ S_RUNNING
Definition: wavefront.hh:66
ComputeUnit::totalCycles
Stats::Scalar totalCycles
Definition: compute_unit.hh:587
WorkitemIdZ
@ WorkitemIdZ
Definition: kernel_code.hh:79
ComputeUnit::numVecOpsExecutedMAD16
Stats::Scalar numVecOpsExecutedMAD16
Definition: compute_unit.hh:581
Wavefront::start
void start(uint64_t _wfDynId, uint64_t _base_ptr)
Definition: wavefront.cc:628
HSAQueueEntry::wgSize
int wgSize(int dim) const
Definition: hsa_queue_entry.hh:122
compute_unit.hh
Wavefront::wgSz
uint32_t wgSz
Definition: wavefront.hh:153
Wavefront::lastAddr
std::vector< Addr > lastAddr
Definition: wavefront.hh:145
NumScalarInitFields
@ NumScalarInitFields
Definition: kernel_code.hh:72
Wavefront::Params
WavefrontParams Params
Definition: wavefront.hh:275
Wavefront::scalarRdGmReqsInPipe
int scalarRdGmReqsInPipe
Definition: wavefront.hh:180
Wavefront::decVMemInstsIssued
void decVMemInstsIssued()
Definition: wavefront.cc:1368
Shader::n_wf
int n_wf
Definition: shader.hh:228
Wavefront::isOldestInstPrivMem
bool isOldestInstPrivMem()
Definition: wavefront.cc:760
RegisterManager::mapSgpr
int mapSgpr(Wavefront *w, int sgprIndex)
Definition: register_manager.cc:101
ComputeUnit::cu_id
int cu_id
Definition: compute_unit.hh:289
ComputeUnit::numVecOpsExecutedFMA32
Stats::Scalar numVecOpsExecutedFMA32
Definition: compute_unit.hh:574
Wavefront::isOldestInstScalarMem
bool isOldestInstScalarMem()
Definition: wavefront.cc:734
ComputeUnit::activeLanesPerLMemInstrDist
Stats::Distribution activeLanesPerLMemInstrDist
Definition: compute_unit.hh:595
ComputeUnit::vectorGlobalMemUnit
WaitClass vectorGlobalMemUnit
Definition: compute_unit.hh:222
Wavefront::status
status_e status
Definition: wavefront.hh:356
ComputeUnit::registerManager
RegisterManager * registerManager
Definition: compute_unit.hh:275
Wavefront::pc
Addr pc() const
Definition: wavefront.cc:1386
std::vector< int >
Wavefront::reserveGmResource
void reserveGmResource(GPUDynInstPtr ii)
Definition: wavefront.cc:819
QueuePtr
@ QueuePtr
Definition: kernel_code.hh:59
ComputeUnit::vrf_lm_bus_latency
Cycles vrf_lm_bus_latency
Definition: compute_unit.hh:317
Wavefront::scalarWrGmReqsInPipe
int scalarWrGmReqsInPipe
Definition: wavefront.hh:181
KernargSegPtr
@ KernargSegPtr
Definition: kernel_code.hh:60
Wavefront::wfId
uint32_t wfId
Definition: wavefront.hh:159
ComputeUnit::numVecOpsExecutedF64
Stats::Scalar numVecOpsExecutedF64
Definition: compute_unit.hh:571
Wavefront::scalarAluGlobalIdx
int scalarAluGlobalIdx
Definition: wavefront.hh:118
Gcn3ISA::VecElemU32
uint32_t VecElemU32
Definition: registers.hh:166
Wavefront::S_BARRIER
@ S_BARRIER
WF is stalled at a barrier.
Definition: wavefront.hh:85
Wavefront::workItemId
std::vector< uint32_t > workItemId[3]
Definition: wavefront.hh:146
Wavefront::dropFetch
bool dropFetch
Definition: wavefront.hh:105
HSAQueueEntry
Definition: hsa_queue_entry.hh:60
WorkgroupIdZ
@ WorkgroupIdZ
Definition: kernel_code.hh:69
HSAQueueEntry::sgprBitEnabled
bool sgprBitEnabled(int bit) const
Definition: hsa_queue_entry.hh:292
Wavefront::actualWgSz
uint32_t actualWgSz[3]
Definition: wavefront.hh:155
Wavefront::numTimesBlockedDueWAXDependencies
Stats::Scalar numTimesBlockedDueWAXDependencies
Definition: wavefront.hh:248
Stats::none
const FlagsType none
Nothing extra to print.
Definition: info.hh:43
Wavefront::incExpInstsIssued
void incExpInstsIssued()
Definition: wavefront.cc:1356
Wavefront::vecRawDistance
Stats::Distribution vecRawDistance
Definition: wavefront.hh:258
Wavefront::scalarOutstandingReqsWrGm
int scalarOutstandingReqsWrGm
Definition: wavefront.hh:175
wavefront.hh
ComputeUnit::numVecOpsExecutedMAD64
Stats::Scalar numVecOpsExecutedMAD64
Definition: compute_unit.hh:583
ComputeUnit::scalarALUs
std::vector< WaitClass > scalarALUs
Definition: compute_unit.hh:246
Wavefront::wfSlotId
const int wfSlotId
Definition: wavefront.hh:89
Wavefront::vmWaitCnt
int vmWaitCnt
the following are used for waitcnt instructions vmWaitCnt: once set, we wait for the oustanding numbe...
Definition: wavefront.hh:350
HSAQueueEntry::amdQueue
_amd_queue_t amdQueue
Keep a copy of the AMD HSA queue because we need info from some of its fields to initialize register ...
Definition: hsa_queue_entry.hh:308
Wavefront::setStatus
void setStatus(status_e newStatus)
Definition: wavefront.cc:591
Wavefront::actualWgSzTotal
uint32_t actualWgSzTotal
Definition: wavefront.hh:156
Wavefront::wrLmReqsInPipe
int wrLmReqsInPipe
Definition: wavefront.hh:178
ArmISA::n
Bitfield< 31 > n
Definition: miscregs_types.hh:450
Wavefront::numTimesBlockedDueRAWDependencies
Stats::Scalar numTimesBlockedDueRAWDependencies
Definition: wavefront.hh:251
Wavefront::S_STALLED
@ S_STALLED
Definition: wavefront.hh:68
Wavefront::ldsChunk
LdsChunk * ldsChunk
Definition: wavefront.hh:215
FlatScratchInit
@ FlatScratchInit
Definition: kernel_code.hh:62
ComputeUnit::instCyclesScMemPerSimd
Stats::Vector instCyclesScMemPerSimd
Definition: compute_unit.hh:505
FetchUnit::flushBuf
void flushBuf(int wfSlotId)
Definition: fetch_unit.cc:305
ComputeUnit::numVecOpsExecutedFMA64
Stats::Scalar numVecOpsExecutedFMA64
Definition: compute_unit.hh:575
Wavefront::outstandingReqs
int outstandingReqs
Definition: wavefront.hh:163
Wavefront::computeUnit
ComputeUnit * computeUnit
Definition: wavefront.hh:99
divCeil
T divCeil(const T &a, const U &b)
Definition: intmath.hh:114
ComputeUnit::srf
std::vector< ScalarRegisterFile * > srf
Definition: compute_unit.hh:294
Wavefront::S_RETURNING
@ S_RETURNING
Definition: wavefront.hh:64
vector_register_file.hh
Clocked::cyclesToTicks
Tick cyclesToTicks(Cycles c) const
Definition: clocked_object.hh:224
ComputeUnit::numVecOpsExecutedF32
Stats::Scalar numVecOpsExecutedF32
Definition: compute_unit.hh:569
Wavefront::discardFetch
void discardFetch()
Definition: wavefront.cc:1235
Wavefront::numInstrExecuted
Stats::Scalar numInstrExecuted
Definition: wavefront.hh:224
Wavefront::scalarOutstandingReqsRdGm
int scalarOutstandingReqsRdGm
Definition: wavefront.hh:173
Wavefront::exec
void exec()
Definition: wavefront.cc:921
Shader::hsail_mode
hsail_mode_e hsail_mode
Definition: shader.hh:215
Shader::vectorInstSrcOperand
Stats::Vector vectorInstSrcOperand
Definition: shader.hh:256
Stats::ScalarBase::value
Counter value() const
Return the current value of this stat as its base type.
Definition: statistics.hh:698
Wavefront::isOldestInstVectorALU
bool isOldestInstVectorALU()
Definition: wavefront.cc:693
HSAQueueEntry::hostAMDQueueAddr
Addr hostAMDQueueAddr
Host-side addr of the amd_queue_t on which this task was queued.
Definition: hsa_queue_entry.hh:301
Wavefront::localMem
int localMem
Definition: wavefront.hh:120
Wavefront::isOldestInstWaitcnt
bool isOldestInstWaitcnt()
Definition: wavefront.cc:661
Wavefront::releaseBarrier
void releaseBarrier()
Definition: wavefront.cc:1457
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
Wavefront::freeResources
void freeResources()
Definition: wavefront.cc:800
Wavefront::setWaitCnts
void setWaitCnts(int vm_wait_cnt, int exp_wait_cnt, int lgkm_wait_cnt)
Definition: wavefront.cc:1291
RegisterManager::vrfPoolMgrs
std::vector< PoolManager * > vrfPoolMgrs
Definition: register_manager.hh:84
HSAQueueEntry::wgId
int wgId(int dim) const
Definition: hsa_queue_entry.hh:210
ComputeUnit::idleCUTimeout
Tick idleCUTimeout
Definition: compute_unit.hh:346
ComputeUnit::idleWfs
int idleWfs
Definition: compute_unit.hh:347
ArmISA::d
Bitfield< 9 > d
Definition: miscregs_types.hh:60
Wavefront::startSgprIndex
uint32_t startSgprIndex
Definition: wavefront.hh:194
Wavefront::lastNonIdleTick
Tick lastNonIdleTick
Definition: wavefront.hh:107
ComputeUnit::vrf
std::vector< VectorRegisterFile * > vrf
Definition: compute_unit.hh:292
WaitClass::set
void set(uint64_t i)
Definition: misc.hh:79
ComputeUnit::instExecPerSimd
std::vector< uint64_t > instExecPerSimd
Definition: compute_unit.hh:329
Wavefront::S_WAITCNT
@ S_WAITCNT
wavefront has unsatisfied wait counts
Definition: wavefront.hh:81
Wavefront::regStats
void regStats()
Callback to set stat parameters.
Definition: wavefront.cc:106
Wavefront::freeRegisterFile
void freeRegisterFile()
Freeing VRF space.
Definition: wavefront.cc:1410
scalar_register_file.hh
Wavefront::outstandingReqsRdGm
int outstandingReqsRdGm
Definition: wavefront.hh:169
ComputeUnit::instInterleave
Stats::VectorDistribution instInterleave
Definition: compute_unit.hh:326
HSAQueueEntry::gridSize
int gridSize(int dim) const
Definition: hsa_queue_entry.hh:129
ComputeUnit::numVecOpsExecutedMAC32
Stats::Scalar numVecOpsExecutedMAC32
Definition: compute_unit.hh:578
gpu_dyn_inst.hh
WFBarrier
WF barrier slots.
Definition: compute_unit.hh:87
Wavefront::flatGmUnitId
int flatGmUnitId
Definition: wavefront.hh:97
GridWorkgroupCountX
@ GridWorkgroupCountX
Definition: kernel_code.hh:64
FetchStage::fetchUnit
FetchUnit & fetchUnit(int simdId)
Definition: fetch_stage.hh:65
ComputeUnit::execRateDist
Stats::Distribution execRateDist
Definition: compute_unit.hh:563
Wavefront::validateRequestCounters
void validateRequestCounters()
Definition: wavefront.cc:805
Wavefront::expInstsIssued
int expInstsIssued
Definition: wavefront.hh:354
ComputeUnit::vrfToLocalMemPipeBus
WaitClass vrfToLocalMemPipeBus
Definition: compute_unit.hh:228
ComputeUnit::fetchStage
FetchStage fetchStage
Definition: compute_unit.hh:277
Wavefront::isLmInstruction
bool isLmInstruction(GPUDynInstPtr ii)
Definition: wavefront.cc:650
Wavefront::maxSgprs
uint32_t maxSgprs
Definition: wavefront.hh:126
WorkitemIdX
@ WorkitemIdX
Definition: kernel_code.hh:77
NumVectorInitFields
@ NumVectorInitFields
Definition: kernel_code.hh:80
ComputeUnit::scalarMemUnit
WaitClass scalarMemUnit
Definition: compute_unit.hh:238
ComputeUnit::issuePeriod
Cycles issuePeriod
Definition: compute_unit.hh:310
Wavefront::isOldestInstLMem
bool isOldestInstLMem()
Definition: wavefront.cc:747
ComputeUnit::numVecOpsExecuted
Stats::Scalar numVecOpsExecuted
Definition: compute_unit.hh:565
ComputeUnit::lastExecCycle
std::vector< uint64_t > lastExecCycle
Definition: compute_unit.hh:320
Wavefront::simdId
const int simdId
Definition: wavefront.hh:92
ComputeUnit::srfToScalarMemPipeBus
WaitClass srfToScalarMemPipeBus
Definition: compute_unit.hh:236
ComputeUnit::numVecOpsExecutedMAD32
Stats::Scalar numVecOpsExecutedMAD32
Definition: compute_unit.hh:582
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Wavefront::lastInstExec
uint64_t lastInstExec
Definition: wavefront.hh:254
Wavefront::isOldestInstGMem
bool isOldestInstGMem()
Definition: wavefront.cc:721
Stats::DataWrap::name
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:274
Wavefront::rdLmReqsInPipe
int rdLmReqsInPipe
Definition: wavefront.hh:176
Wavefront::S_STOPPED
@ S_STOPPED
Definition: wavefront.hh:62
Wavefront::lgkmWaitCnt
int lgkmWaitCnt
Definition: wavefront.hh:352
Wavefront::hasBarrier
bool hasBarrier() const
Definition: wavefront.cc:1451
HSAQueueEntry::kernargAddr
Addr kernargAddr() const
Definition: hsa_queue_entry.hh:184
Wavefront::computeActualWgSz
void computeActualWgSz(HSAQueueEntry *task)
Definition: wavefront.cc:1426
Wavefront::nextInstr
GPUDynInstPtr nextInstr()
Definition: wavefront.cc:1216
Wavefront::rawDist
std::unordered_map< int, uint64_t > rawDist
Definition: wavefront.hh:261
Wavefront::decLGKMInstsIssued
void decLGKMInstsIssued()
Definition: wavefront.cc:1380
Wavefront::decExpInstsIssued
void decExpInstsIssued()
Definition: wavefront.cc:1374
Wavefront::pendingFetch
bool pendingFetch
Definition: wavefront.hh:104
Wavefront::outstandingReqsRdLm
int outstandingReqsRdLm
Definition: wavefront.hh:171
Wavefront::waitCntsSatisfied
bool waitCntsSatisfied()
Definition: wavefront.cc:1248
ComputeUnit::getTokenManager
TokenManager * getTokenManager()
Definition: compute_unit.hh:981
Wavefront::execUnitId
int execUnitId
Definition: wavefront.hh:95
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
ComputeUnit::numVecOpsExecutedMAC64
Stats::Scalar numVecOpsExecutedMAC64
Definition: compute_unit.hh:579
Wavefront::readsPerWrite
Stats::Distribution readsPerWrite
Definition: wavefront.hh:265
Wavefront::schResourceStalls
Stats::Scalar schResourceStalls
Definition: wavefront.hh:238
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
Wavefront::isGmInstruction
bool isGmInstruction(GPUDynInstPtr ii)
Definition: wavefront.cc:639
Wavefront::reserveLmResource
void reserveLmResource(GPUDynInstPtr ii)
Definition: wavefront.cc:849
Wavefront::memTraceBusy
int memTraceBusy
Definition: wavefront.hh:183
_amd_queue_s::scratch_backing_memory_location
uint64_t scratch_backing_memory_location
Definition: hsa_queue.hh:83
Wavefront::Wavefront
Wavefront(const Params *p)
Definition: wavefront.cc:52
Wavefront::isOldestInstBarrier
bool isOldestInstBarrier()
Definition: wavefront.cc:708
Wavefront::schLdsArbStalls
Stats::Scalar schLdsArbStalls
Definition: wavefront.hh:244
WorkitemIdY
@ WorkitemIdY
Definition: kernel_code.hh:78
ComputeUnit::updateInstStats
void updateInstStats(GPUDynInstPtr gpuDynInst)
Definition: compute_unit.cc:2350
ComputeUnit::numVecOpsExecutedTwoOpFP
Stats::Scalar numVecOpsExecutedTwoOpFP
Definition: compute_unit.hh:585
Stats::Distribution::init
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
Definition: statistics.hh:2634
Wavefront::_pc
Addr _pc
Definition: wavefront.hh:357
Wavefront
Definition: wavefront.hh:57
Shader::SIMT
@ SIMT
Definition: shader.hh:123
ComputeUnit::numVecOpsExecutedMAC16
Stats::Scalar numVecOpsExecutedMAC16
Definition: compute_unit.hh:577
Wavefront::initRegState
void initRegState(HSAQueueEntry *task, int wgSizeInWorkItems)
Definition: wavefront.cc:190
Wavefront::execMask
VectorMask & execMask()
Definition: wavefront.cc:1398
Wavefront::wgId
uint32_t wgId
Definition: wavefront.hh:152
ComputeUnit::wfSize
int wfSize() const
Definition: compute_unit.hh:397
GPUDynInstPtr
std::shared_ptr< GPUDynInst > GPUDynInstPtr
Definition: misc.hh:48
Wavefront::workGroupId
uint32_t workGroupId[3]
Definition: wavefront.hh:149
Stats::DistBase::sample
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1924
Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
Gcn3ISA::ScalarRegU32
uint32_t ScalarRegU32
Definition: registers.hh:154
WorkgroupIdY
@ WorkgroupIdY
Definition: kernel_code.hh:68
_amd_queue_s::compute_tmpring_size_wavesize
uint32_t compute_tmpring_size_wavesize
Definition: hsa_queue.hh:80
Wavefront::schRfAccessStalls
Stats::Scalar schRfAccessStalls
Definition: wavefront.hh:236
Wavefront::init
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: wavefront.cc:175
Wavefront::instructionBuffer
std::deque< GPUDynInstPtr > instructionBuffer
Definition: wavefront.hh:102
RegisterManager::mapVgpr
int mapVgpr(Wavefront *w, int vgprIndex)
Definition: register_manager.cc:94
Wavefront::~Wavefront
~Wavefront()
Definition: wavefront.cc:586
Wavefront::oldDgprTcnt
uint64_t oldDgprTcnt
Definition: wavefront.hh:208
Wavefront::expWaitCnt
int expWaitCnt
Definition: wavefront.hh:351
Wavefront::incVMemInstsIssued
void incVMemInstsIssued()
Definition: wavefront.cc:1350
Wavefront::outstandingReqsWrLm
int outstandingReqsWrLm
Definition: wavefront.hh:167
Wavefront::_gpuISA
TheGpuISA::GPUISA _gpuISA
Definition: wavefront.hh:329
Gcn3ISA::VecRegContainerU32
VecRegU32::Container VecRegContainerU32
Definition: registers.hh:198
Wavefront::scalarAlu
int scalarAlu
Definition: wavefront.hh:114
Wavefront::workItemFlatId
std::vector< uint32_t > workItemFlatId
Definition: wavefront.hh:147
Wavefront::reservedVectorRegs
int reservedVectorRegs
Definition: wavefront.hh:186
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
Wavefront::rdGmReqsInPipe
int rdGmReqsInPipe
Definition: wavefront.hh:177
Wavefront::flatLmUnitId
int flatLmUnitId
Definition: wavefront.hh:96
Wavefront::oldDgpr
std::vector< uint64_t > oldDgpr
Definition: wavefront.hh:204
GridWorkgroupCountY
@ GridWorkgroupCountY
Definition: kernel_code.hh:65
VectorMask
std::bitset< std::numeric_limits< unsigned long long >::digits > VectorMask
Definition: misc.hh:44
Wavefront::stopFetch
bool stopFetch()
Definition: wavefront.cc:786
Wavefront::workGroupSz
uint32_t workGroupSz[3]
Definition: wavefront.hh:150
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
Wavefront::reservedScalarRegs
int reservedScalarRegs
Definition: wavefront.hh:188
ComputeUnit::pipeMap
std::unordered_set< uint64_t > pipeMap
Definition: compute_unit.hh:273
Stats::DataWrap::desc
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:307
ComputeUnit::instCyclesVMemPerSimd
Stats::Vector instCyclesVMemPerSimd
Definition: compute_unit.hh:504
ComputeUnit::mapWaveToScalarAlu
int mapWaveToScalarAlu(Wavefront *w) const
Definition: compute_unit.cc:250
GridWorkgroupCountZ
@ GridWorkgroupCountZ
Definition: kernel_code.hh:66
ComputeUnit::shader
Shader * shader
Definition: compute_unit.hh:356
WFBarrier::InvalidID
static const int InvalidID
Definition: compute_unit.hh:94
Wavefront::status_e
status_e
Definition: wavefront.hh:60
Wavefront::gridSz
uint32_t gridSz[3]
Definition: wavefront.hh:151
Wavefront::lastTrace
uint64_t lastTrace
Definition: wavefront.hh:184
ComputeUnit::activeLanesPerGMemInstrDist
Stats::Distribution activeLanesPerGMemInstrDist
Definition: compute_unit.hh:594
ComputeUnit::numVecOpsExecutedFMA16
Stats::Scalar numVecOpsExecutedFMA16
Definition: compute_unit.hh:573
Wavefront::outstandingReqsWrGm
int outstandingReqsWrGm
Definition: wavefront.hh:165
Wavefront::wfDynId
uint64_t wfDynId
Definition: wavefront.hh:218
Wavefront::reserveResources
std::vector< int > reserveResources()
Definition: wavefront.cc:867
Wavefront::maxVgprs
uint32_t maxVgprs
Definition: wavefront.hh:124
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
Wavefront::incLGKMInstsIssued
void incLGKMInstsIssued()
Definition: wavefront.cc:1362
ComputeUnit::numVectorALUs
int numVectorALUs
Definition: compute_unit.hh:241
WorkgroupInfo
@ WorkgroupInfo
Definition: kernel_code.hh:70
DispatchPtr
@ DispatchPtr
Definition: kernel_code.hh:58
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92

Generated on Wed Sep 30 2020 14:02:12 for gem5 by doxygen 1.8.17