compute_unit.hh revision 11534
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2011-2015 Advanced Micro Devices, Inc.
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only
611308Santhony.gutierrez@amd.com *
711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met:
911308Santhony.gutierrez@amd.com *
1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice,
1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer.
1211308Santhony.gutierrez@amd.com *
1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation
1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution.
1611308Santhony.gutierrez@amd.com *
1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors
1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software
1911308Santhony.gutierrez@amd.com * without specific prior written permission.
2011308Santhony.gutierrez@amd.com *
2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE.
3211308Santhony.gutierrez@amd.com *
3311308Santhony.gutierrez@amd.com * Author: John Kalamatianos, Anthony Gutierrez
3411308Santhony.gutierrez@amd.com */
3511308Santhony.gutierrez@amd.com
3611308Santhony.gutierrez@amd.com#ifndef __COMPUTE_UNIT_HH__
3711308Santhony.gutierrez@amd.com#define __COMPUTE_UNIT_HH__
3811308Santhony.gutierrez@amd.com
3911308Santhony.gutierrez@amd.com#include <deque>
4011308Santhony.gutierrez@amd.com#include <map>
4111308Santhony.gutierrez@amd.com#include <unordered_map>
4211308Santhony.gutierrez@amd.com#include <vector>
4311308Santhony.gutierrez@amd.com
4411308Santhony.gutierrez@amd.com#include "base/callback.hh"
4511308Santhony.gutierrez@amd.com#include "base/statistics.hh"
4611308Santhony.gutierrez@amd.com#include "base/types.hh"
4711308Santhony.gutierrez@amd.com#include "enums/PrefetchType.hh"
4811308Santhony.gutierrez@amd.com#include "gpu-compute/exec_stage.hh"
4911308Santhony.gutierrez@amd.com#include "gpu-compute/fetch_stage.hh"
5011308Santhony.gutierrez@amd.com#include "gpu-compute/global_memory_pipeline.hh"
5111308Santhony.gutierrez@amd.com#include "gpu-compute/local_memory_pipeline.hh"
5211308Santhony.gutierrez@amd.com#include "gpu-compute/qstruct.hh"
5311308Santhony.gutierrez@amd.com#include "gpu-compute/schedule_stage.hh"
5411308Santhony.gutierrez@amd.com#include "gpu-compute/scoreboard_check_stage.hh"
5511308Santhony.gutierrez@amd.com#include "mem/mem_object.hh"
5611308Santhony.gutierrez@amd.com#include "mem/port.hh"
5711308Santhony.gutierrez@amd.com
5811308Santhony.gutierrez@amd.comstatic const int MAX_REGS_FOR_NON_VEC_MEM_INST = 1;
5911308Santhony.gutierrez@amd.comstatic const int MAX_WIDTH_FOR_MEM_INST = 32;
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.comclass NDRange;
6211308Santhony.gutierrez@amd.comclass Shader;
6311308Santhony.gutierrez@amd.comclass VectorRegisterFile;
6411308Santhony.gutierrez@amd.com
6511308Santhony.gutierrez@amd.comstruct ComputeUnitParams;
6611308Santhony.gutierrez@amd.com
6711308Santhony.gutierrez@amd.comenum EXEC_POLICY
6811308Santhony.gutierrez@amd.com{
6911308Santhony.gutierrez@amd.com    OLDEST = 0,
7011308Santhony.gutierrez@amd.com    RR
7111308Santhony.gutierrez@amd.com};
7211308Santhony.gutierrez@amd.com
7311308Santhony.gutierrez@amd.com// List of execution units
7411308Santhony.gutierrez@amd.comenum EXEC_UNIT
7511308Santhony.gutierrez@amd.com{
7611308Santhony.gutierrez@amd.com    SIMD0 = 0,
7711308Santhony.gutierrez@amd.com    SIMD1,
7811308Santhony.gutierrez@amd.com    SIMD2,
7911308Santhony.gutierrez@amd.com    SIMD3,
8011308Santhony.gutierrez@amd.com    GLBMEM_PIPE,
8111308Santhony.gutierrez@amd.com    LDSMEM_PIPE,
8211308Santhony.gutierrez@amd.com    NUM_UNITS
8311308Santhony.gutierrez@amd.com};
8411308Santhony.gutierrez@amd.com
8511308Santhony.gutierrez@amd.comenum TLB_CACHE
8611308Santhony.gutierrez@amd.com{
8711308Santhony.gutierrez@amd.com    TLB_MISS_CACHE_MISS = 0,
8811308Santhony.gutierrez@amd.com    TLB_MISS_CACHE_HIT,
8911308Santhony.gutierrez@amd.com    TLB_HIT_CACHE_MISS,
9011308Santhony.gutierrez@amd.com    TLB_HIT_CACHE_HIT
9111308Santhony.gutierrez@amd.com};
9211308Santhony.gutierrez@amd.com
9311308Santhony.gutierrez@amd.comclass ComputeUnit : public MemObject
9411308Santhony.gutierrez@amd.com{
9511308Santhony.gutierrez@amd.com  public:
9611308Santhony.gutierrez@amd.com    FetchStage fetchStage;
9711308Santhony.gutierrez@amd.com    ScoreboardCheckStage scoreboardCheckStage;
9811308Santhony.gutierrez@amd.com    ScheduleStage scheduleStage;
9911308Santhony.gutierrez@amd.com    ExecStage execStage;
10011308Santhony.gutierrez@amd.com    GlobalMemPipeline globalMemoryPipe;
10111308Santhony.gutierrez@amd.com    LocalMemPipeline localMemoryPipe;
10211308Santhony.gutierrez@amd.com
10311308Santhony.gutierrez@amd.com    // Buffers used to communicate between various pipeline stages
10411308Santhony.gutierrez@amd.com
10511308Santhony.gutierrez@amd.com    // List of waves which are ready to be scheduled.
10611308Santhony.gutierrez@amd.com    // Each execution resource has a ready list. readyList is
10711308Santhony.gutierrez@amd.com    // used to communicate between scoreboardCheck stage and
10811308Santhony.gutierrez@amd.com    // schedule stage
10911308Santhony.gutierrez@amd.com    // TODO: make enum to index readyList
11011308Santhony.gutierrez@amd.com    std::vector<std::vector<Wavefront*>> readyList;
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com    // Stores the status of waves. A READY implies the
11311308Santhony.gutierrez@amd.com    // wave is ready to be scheduled this cycle and
11411308Santhony.gutierrez@amd.com    // is already present in the readyList. waveStatusList is
11511308Santhony.gutierrez@amd.com    // used to communicate between scoreboardCheck stage and
11611308Santhony.gutierrez@amd.com    // schedule stage
11711308Santhony.gutierrez@amd.com    // TODO: convert std::pair to a class to increase readability
11811308Santhony.gutierrez@amd.com    std::vector<std::vector<std::pair<Wavefront*, WAVE_STATUS>>> waveStatusList;
11911308Santhony.gutierrez@amd.com
12011308Santhony.gutierrez@amd.com    // List of waves which will be dispatched to
12111308Santhony.gutierrez@amd.com    // each execution resource. A FILLED implies
12211308Santhony.gutierrez@amd.com    // dispatch list is non-empty and
12311308Santhony.gutierrez@amd.com    // execution unit has something to execute
12411308Santhony.gutierrez@amd.com    // this cycle. Currently, the dispatch list of
12511308Santhony.gutierrez@amd.com    // an execution resource can hold only one wave because
12611308Santhony.gutierrez@amd.com    // an execution resource can execute only one wave in a cycle.
12711308Santhony.gutierrez@amd.com    // dispatchList is used to communicate between schedule
12811308Santhony.gutierrez@amd.com    // and exec stage
12911308Santhony.gutierrez@amd.com    // TODO: convert std::pair to a class to increase readability
13011308Santhony.gutierrez@amd.com    std::vector<std::pair<Wavefront*, DISPATCH_STATUS>> dispatchList;
13111308Santhony.gutierrez@amd.com
13211308Santhony.gutierrez@amd.com    int rrNextMemID; // used by RR WF exec policy to cycle through WF's
13311308Santhony.gutierrez@amd.com    int rrNextALUWp;
13411308Santhony.gutierrez@amd.com    typedef ComputeUnitParams Params;
13511308Santhony.gutierrez@amd.com    std::vector<std::vector<Wavefront*>> wfList;
13611308Santhony.gutierrez@amd.com    int cu_id;
13711308Santhony.gutierrez@amd.com
13811308Santhony.gutierrez@amd.com    // array of vector register files, one per SIMD
13911308Santhony.gutierrez@amd.com    std::vector<VectorRegisterFile*> vrf;
14011308Santhony.gutierrez@amd.com    // Number of vector ALU units (SIMDs) in CU
14111308Santhony.gutierrez@amd.com    int numSIMDs;
14211308Santhony.gutierrez@amd.com    // number of pipe stages for bypassing data to next dependent single
14311308Santhony.gutierrez@amd.com    // precision vector instruction inside the vector ALU pipeline
14411308Santhony.gutierrez@amd.com    int spBypassPipeLength;
14511308Santhony.gutierrez@amd.com    // number of pipe stages for bypassing data to next dependent double
14611308Santhony.gutierrez@amd.com    // precision vector instruction inside the vector ALU pipeline
14711308Santhony.gutierrez@amd.com    int dpBypassPipeLength;
14811308Santhony.gutierrez@amd.com    // number of cycles per issue period
14911308Santhony.gutierrez@amd.com    int issuePeriod;
15011308Santhony.gutierrez@amd.com
15111308Santhony.gutierrez@amd.com    // Number of global and local memory execution resources in CU
15211308Santhony.gutierrez@amd.com    int numGlbMemUnits;
15311308Santhony.gutierrez@amd.com    int numLocMemUnits;
15411308Santhony.gutierrez@amd.com    // tracks the last cycle a vector instruction was executed on a SIMD
15511308Santhony.gutierrez@amd.com    std::vector<uint64_t> lastExecCycle;
15611308Santhony.gutierrez@amd.com
15711308Santhony.gutierrez@amd.com    // true if we allow a separate TLB per lane
15811308Santhony.gutierrez@amd.com    bool perLaneTLB;
15911308Santhony.gutierrez@amd.com    // if 0, TLB prefetching is off.
16011308Santhony.gutierrez@amd.com    int prefetchDepth;
16111308Santhony.gutierrez@amd.com    // if fixed-stride prefetching, this is the stride.
16211308Santhony.gutierrez@amd.com    int prefetchStride;
16311308Santhony.gutierrez@amd.com
16411534Sjohn.kalamatianos@amd.com    std::vector<Addr> lastVaddrCU;
16511534Sjohn.kalamatianos@amd.com    std::vector<std::vector<Addr>> lastVaddrSimd;
16611308Santhony.gutierrez@amd.com    std::vector<std::vector<std::vector<Addr>>> lastVaddrWF;
16711308Santhony.gutierrez@amd.com    Enums::PrefetchType prefetchType;
16811308Santhony.gutierrez@amd.com    EXEC_POLICY exec_policy;
16911308Santhony.gutierrez@amd.com
17011308Santhony.gutierrez@amd.com    bool xact_cas_mode;
17111308Santhony.gutierrez@amd.com    bool debugSegFault;
17211308Santhony.gutierrez@amd.com    bool functionalTLB;
17311308Santhony.gutierrez@amd.com    bool localMemBarrier;
17411308Santhony.gutierrez@amd.com
17511308Santhony.gutierrez@amd.com    /*
17611308Santhony.gutierrez@amd.com     * for Counting page accesses
17711308Santhony.gutierrez@amd.com     *
17811308Santhony.gutierrez@amd.com     * cuExitCallback inherits from Callback. When you register a callback
17911308Santhony.gutierrez@amd.com     * function as an exit callback, it will get added to an exit callback
18011308Santhony.gutierrez@amd.com     * queue, such that on simulation exit, all callbacks in the callback
18111308Santhony.gutierrez@amd.com     * queue will have their process() function called.
18211308Santhony.gutierrez@amd.com     */
18311308Santhony.gutierrez@amd.com    bool countPages;
18411308Santhony.gutierrez@amd.com
18511308Santhony.gutierrez@amd.com    Shader *shader;
18611308Santhony.gutierrez@amd.com    uint32_t barrier_id;
18711308Santhony.gutierrez@amd.com    // vector of Vector ALU (MACC) pipelines
18811308Santhony.gutierrez@amd.com    std::vector<WaitClass> aluPipe;
18911308Santhony.gutierrez@amd.com    // minimum issue period per SIMD unit (in cycles)
19011308Santhony.gutierrez@amd.com    std::vector<WaitClass> wfWait;
19111308Santhony.gutierrez@amd.com
19211308Santhony.gutierrez@amd.com    // Resource control for Vector Register File->Global Memory pipe buses
19311308Santhony.gutierrez@amd.com    std::vector<WaitClass> vrfToGlobalMemPipeBus;
19411308Santhony.gutierrez@amd.com    // Resource control for Vector Register File->Local Memory pipe buses
19511308Santhony.gutierrez@amd.com    std::vector<WaitClass> vrfToLocalMemPipeBus;
19611308Santhony.gutierrez@amd.com    int nextGlbMemBus;
19711308Santhony.gutierrez@amd.com    int nextLocMemBus;
19811308Santhony.gutierrez@amd.com    // Resource control for global memory to VRF data/address bus
19911308Santhony.gutierrez@amd.com    WaitClass glbMemToVrfBus;
20011308Santhony.gutierrez@amd.com    // Resource control for local memory to VRF data/address bus
20111308Santhony.gutierrez@amd.com    WaitClass locMemToVrfBus;
20211308Santhony.gutierrez@amd.com
20311308Santhony.gutierrez@amd.com    uint32_t vrfToCoalescerBusWidth; // VRF->Coalescer data bus width in bytes
20411308Santhony.gutierrez@amd.com    uint32_t coalescerToVrfBusWidth; // Coalescer->VRF data bus width in bytes
20511308Santhony.gutierrez@amd.com    uint32_t numCyclesPerStoreTransfer;  // number of cycles per vector store
20611308Santhony.gutierrez@amd.com    uint32_t numCyclesPerLoadTransfer;  // number of cycles per vector load
20711308Santhony.gutierrez@amd.com
20811308Santhony.gutierrez@amd.com    Tick req_tick_latency;
20911308Santhony.gutierrez@amd.com    Tick resp_tick_latency;
21011308Santhony.gutierrez@amd.com
21111308Santhony.gutierrez@amd.com    // number of vector registers being reserved for each SIMD unit
21211308Santhony.gutierrez@amd.com    std::vector<int> vectorRegsReserved;
21311308Santhony.gutierrez@amd.com    // number of vector registers per SIMD unit
21411308Santhony.gutierrez@amd.com    uint32_t numVecRegsPerSimd;
21511308Santhony.gutierrez@amd.com    // Support for scheduling VGPR status update events
21611308Santhony.gutierrez@amd.com    std::vector<std::pair<uint32_t, uint32_t> > regIdxVec;
21711308Santhony.gutierrez@amd.com    std::vector<uint64_t> timestampVec;
21811308Santhony.gutierrez@amd.com    std::vector<uint8_t>  statusVec;
21911308Santhony.gutierrez@amd.com
22011308Santhony.gutierrez@amd.com    void
22111308Santhony.gutierrez@amd.com    registerEvent(uint32_t simdId,
22211308Santhony.gutierrez@amd.com                  uint32_t regIdx,
22311308Santhony.gutierrez@amd.com                  uint32_t operandSize,
22411308Santhony.gutierrez@amd.com                  uint64_t when,
22511308Santhony.gutierrez@amd.com                  uint8_t newStatus) {
22611308Santhony.gutierrez@amd.com        regIdxVec.push_back(std::make_pair(simdId, regIdx));
22711308Santhony.gutierrez@amd.com        timestampVec.push_back(when);
22811308Santhony.gutierrez@amd.com        statusVec.push_back(newStatus);
22911308Santhony.gutierrez@amd.com        if (operandSize > 4) {
23011308Santhony.gutierrez@amd.com            regIdxVec.push_back(std::make_pair(simdId,
23111308Santhony.gutierrez@amd.com                                               ((regIdx + 1) %
23211308Santhony.gutierrez@amd.com                                                numVecRegsPerSimd)));
23311308Santhony.gutierrez@amd.com            timestampVec.push_back(when);
23411308Santhony.gutierrez@amd.com            statusVec.push_back(newStatus);
23511308Santhony.gutierrez@amd.com        }
23611308Santhony.gutierrez@amd.com    }
23711308Santhony.gutierrez@amd.com
23811308Santhony.gutierrez@amd.com    void updateEvents();
23911308Santhony.gutierrez@amd.com
24011308Santhony.gutierrez@amd.com    // this hash map will keep track of page divergence
24111308Santhony.gutierrez@amd.com    // per memory instruction per wavefront. The hash map
24211308Santhony.gutierrez@amd.com    // is cleared in GPUDynInst::updateStats() in gpu_dyn_inst.cc.
24311308Santhony.gutierrez@amd.com    std::map<Addr, int> pagesTouched;
24411308Santhony.gutierrez@amd.com
24511308Santhony.gutierrez@amd.com    ComputeUnit(const Params *p);
24611308Santhony.gutierrez@amd.com    ~ComputeUnit();
24711308Santhony.gutierrez@amd.com    int spBypassLength() { return spBypassPipeLength; };
24811308Santhony.gutierrez@amd.com    int dpBypassLength() { return dpBypassPipeLength; };
24911308Santhony.gutierrez@amd.com    int storeBusLength() { return numCyclesPerStoreTransfer; };
25011308Santhony.gutierrez@amd.com    int loadBusLength() { return numCyclesPerLoadTransfer; };
25111308Santhony.gutierrez@amd.com    int wfSize() const { return wavefrontSize; };
25211308Santhony.gutierrez@amd.com
25311308Santhony.gutierrez@amd.com    void resizeRegFiles(int num_cregs, int num_sregs, int num_dregs);
25411308Santhony.gutierrez@amd.com    void exec();
25511308Santhony.gutierrez@amd.com    void initiateFetch(Wavefront *wavefront);
25611308Santhony.gutierrez@amd.com    void fetch(PacketPtr pkt, Wavefront *wavefront);
25711308Santhony.gutierrez@amd.com    void FillKernelState(Wavefront *w, NDRange *ndr);
25811308Santhony.gutierrez@amd.com
25911308Santhony.gutierrez@amd.com    void StartWF(Wavefront *w, WFContext *wfCtx, int trueWgSize[],
26011308Santhony.gutierrez@amd.com                 int trueWgSizeTotal);
26111308Santhony.gutierrez@amd.com
26211308Santhony.gutierrez@amd.com    void InitializeWFContext(WFContext *wfCtx, NDRange *ndr, int cnt,
26311308Santhony.gutierrez@amd.com                             int trueWgSize[], int trueWgSizeTotal,
26411308Santhony.gutierrez@amd.com                             LdsChunk *ldsChunk, uint64_t origSpillMemStart);
26511308Santhony.gutierrez@amd.com
26611308Santhony.gutierrez@amd.com    void StartWorkgroup(NDRange *ndr);
26711308Santhony.gutierrez@amd.com    int ReadyWorkgroup(NDRange *ndr);
26811308Santhony.gutierrez@amd.com
26911308Santhony.gutierrez@amd.com    bool isVecAlu(int unitId) { return unitId >= SIMD0 && unitId <= SIMD3; }
27011308Santhony.gutierrez@amd.com    bool isGlbMem(int unitId) { return unitId == GLBMEM_PIPE; }
27111308Santhony.gutierrez@amd.com    bool isShrMem(int unitId) { return unitId == LDSMEM_PIPE; }
27211308Santhony.gutierrez@amd.com    int GlbMemUnitId() { return GLBMEM_PIPE; }
27311308Santhony.gutierrez@amd.com    int ShrMemUnitId() { return LDSMEM_PIPE; }
27411308Santhony.gutierrez@amd.com    int nextGlbRdBus() { return (++nextGlbMemBus) % numGlbMemUnits; }
27511308Santhony.gutierrez@amd.com    int nextLocRdBus() { return (++nextLocMemBus) % numLocMemUnits; }
27611308Santhony.gutierrez@amd.com    /* This function cycles through all the wavefronts in all the phases to see
27711308Santhony.gutierrez@amd.com     * if all of the wavefronts which should be associated with one barrier
27811308Santhony.gutierrez@amd.com     * (denoted with _barrier_id), are all at the same barrier in the program
27911308Santhony.gutierrez@amd.com     * (denoted by bcnt). When the number at the barrier matches bslots, then
28011308Santhony.gutierrez@amd.com     * return true.
28111308Santhony.gutierrez@amd.com     */
28211308Santhony.gutierrez@amd.com    int AllAtBarrier(uint32_t _barrier_id, uint32_t bcnt, uint32_t bslots);
28311308Santhony.gutierrez@amd.com    bool cedeSIMD(int simdId, int wfSlotId);
28411308Santhony.gutierrez@amd.com
28511308Santhony.gutierrez@amd.com    template<typename c0, typename c1> void doSmReturn(GPUDynInstPtr gpuDynInst);
28611308Santhony.gutierrez@amd.com    virtual void init();
28711308Santhony.gutierrez@amd.com    void sendRequest(GPUDynInstPtr gpuDynInst, int index, PacketPtr pkt);
28811308Santhony.gutierrez@amd.com    void sendSyncRequest(GPUDynInstPtr gpuDynInst, int index, PacketPtr pkt);
28911308Santhony.gutierrez@amd.com    void injectGlobalMemFence(GPUDynInstPtr gpuDynInst,
29011308Santhony.gutierrez@amd.com                              bool kernelLaunch=true,
29111308Santhony.gutierrez@amd.com                              RequestPtr req=nullptr);
29211308Santhony.gutierrez@amd.com    void handleMemPacket(PacketPtr pkt, int memport_index);
29311308Santhony.gutierrez@amd.com    bool processTimingPacket(PacketPtr pkt);
29411308Santhony.gutierrez@amd.com    void processFetchReturn(PacketPtr pkt);
29511308Santhony.gutierrez@amd.com    void updatePageDivergenceDist(Addr addr);
29611308Santhony.gutierrez@amd.com
29711308Santhony.gutierrez@amd.com    MasterID masterId() { return _masterId; }
29811308Santhony.gutierrez@amd.com
29911308Santhony.gutierrez@amd.com    bool isDone() const;
30011308Santhony.gutierrez@amd.com    bool isSimdDone(uint32_t) const;
30111308Santhony.gutierrez@amd.com
30211308Santhony.gutierrez@amd.com  protected:
30311308Santhony.gutierrez@amd.com    MasterID _masterId;
30411308Santhony.gutierrez@amd.com
30511308Santhony.gutierrez@amd.com    LdsState &lds;
30611308Santhony.gutierrez@amd.com
30711308Santhony.gutierrez@amd.com  public:
30811308Santhony.gutierrez@amd.com    // the following stats compute the avg. TLB accesslatency per
30911308Santhony.gutierrez@amd.com    // uncoalesced request (only for data)
31011308Santhony.gutierrez@amd.com    Stats::Scalar tlbRequests;
31111308Santhony.gutierrez@amd.com    Stats::Scalar tlbCycles;
31211308Santhony.gutierrez@amd.com    Stats::Formula tlbLatency;
31311308Santhony.gutierrez@amd.com    // hitsPerTLBLevel[x] are the hits in Level x TLB. x = 0 is the page table.
31411308Santhony.gutierrez@amd.com    Stats::Vector hitsPerTLBLevel;
31511308Santhony.gutierrez@amd.com
31611308Santhony.gutierrez@amd.com    Stats::Scalar ldsBankAccesses;
31711308Santhony.gutierrez@amd.com    Stats::Distribution ldsBankConflictDist;
31811308Santhony.gutierrez@amd.com
31911308Santhony.gutierrez@amd.com    // over all memory instructions executed over all wavefronts
32011308Santhony.gutierrez@amd.com    // how many touched 0-4 pages, 4-8, ..., 60-64 pages
32111308Santhony.gutierrez@amd.com    Stats::Distribution pageDivergenceDist;
32211308Santhony.gutierrez@amd.com    Stats::Scalar dynamicGMemInstrCnt;
32311308Santhony.gutierrez@amd.com    Stats::Scalar dynamicLMemInstrCnt;
32411308Santhony.gutierrez@amd.com
32511308Santhony.gutierrez@amd.com    Stats::Scalar wgBlockedDueLdsAllocation;
32611308Santhony.gutierrez@amd.com    // Number of instructions executed, i.e. if 64 (or 32 or 7) lanes are active
32711308Santhony.gutierrez@amd.com    // when the instruction is committed, this number is still incremented by 1
32811308Santhony.gutierrez@amd.com    Stats::Scalar numInstrExecuted;
32911308Santhony.gutierrez@amd.com    // Number of cycles among successive instruction executions across all
33011308Santhony.gutierrez@amd.com    // wavefronts of the same CU
33111308Santhony.gutierrez@amd.com    Stats::Distribution execRateDist;
33211308Santhony.gutierrez@amd.com    // number of individual vector operations executed
33311308Santhony.gutierrez@amd.com    Stats::Scalar numVecOpsExecuted;
33411308Santhony.gutierrez@amd.com    // Total cycles that something is running on the GPU
33511308Santhony.gutierrez@amd.com    Stats::Scalar totalCycles;
33611308Santhony.gutierrez@amd.com    Stats::Formula vpc; // vector ops per cycle
33711308Santhony.gutierrez@amd.com    Stats::Formula ipc; // vector instructions per cycle
33811308Santhony.gutierrez@amd.com    Stats::Distribution controlFlowDivergenceDist;
33911308Santhony.gutierrez@amd.com    Stats::Distribution activeLanesPerGMemInstrDist;
34011308Santhony.gutierrez@amd.com    Stats::Distribution activeLanesPerLMemInstrDist;
34111308Santhony.gutierrez@amd.com    // number of vector ALU instructions received
34211308Santhony.gutierrez@amd.com    Stats::Formula numALUInstsExecuted;
34311308Santhony.gutierrez@amd.com    // number of times a WG can not start due to lack of free VGPRs in SIMDs
34411308Santhony.gutierrez@amd.com    Stats::Scalar numTimesWgBlockedDueVgprAlloc;
34511308Santhony.gutierrez@amd.com    Stats::Scalar numCASOps;
34611308Santhony.gutierrez@amd.com    Stats::Scalar numFailedCASOps;
34711308Santhony.gutierrez@amd.com    Stats::Scalar completedWfs;
34811308Santhony.gutierrez@amd.com    // flag per vector SIMD unit that is set when there is at least one
34911308Santhony.gutierrez@amd.com    // WV that has a vector ALU instruction as the oldest in its
35011308Santhony.gutierrez@amd.com    // Instruction Buffer: Defined in the Scoreboard stage, consumed
35111308Santhony.gutierrez@amd.com    // by the Execute stage.
35211308Santhony.gutierrez@amd.com    std::vector<bool> vectorAluInstAvail;
35311308Santhony.gutierrez@amd.com    // number of available (oldest) LDS instructions that could have
35411308Santhony.gutierrez@amd.com    // been issued to the LDS at a specific issue slot
35511308Santhony.gutierrez@amd.com    int shrMemInstAvail;
35611308Santhony.gutierrez@amd.com    // number of available Global memory instructions that could have
35711308Santhony.gutierrez@amd.com    // been issued to TCP at a specific issue slot
35811308Santhony.gutierrez@amd.com    int glbMemInstAvail;
35911308Santhony.gutierrez@amd.com
36011308Santhony.gutierrez@amd.com    void
36111308Santhony.gutierrez@amd.com    regStats();
36211308Santhony.gutierrez@amd.com
36311308Santhony.gutierrez@amd.com    LdsState &
36411308Santhony.gutierrez@amd.com    getLds() const
36511308Santhony.gutierrez@amd.com    {
36611308Santhony.gutierrez@amd.com        return lds;
36711308Santhony.gutierrez@amd.com    }
36811308Santhony.gutierrez@amd.com
36911308Santhony.gutierrez@amd.com    int32_t
37011308Santhony.gutierrez@amd.com    getRefCounter(const uint32_t dispatchId, const uint32_t wgId) const;
37111308Santhony.gutierrez@amd.com
37211308Santhony.gutierrez@amd.com    bool
37311308Santhony.gutierrez@amd.com    sendToLds(GPUDynInstPtr gpuDynInst) __attribute__((warn_unused_result));
37411308Santhony.gutierrez@amd.com
37511308Santhony.gutierrez@amd.com    typedef std::unordered_map<Addr, std::pair<int, int>> pageDataStruct;
37611308Santhony.gutierrez@amd.com    pageDataStruct pageAccesses;
37711308Santhony.gutierrez@amd.com
37811308Santhony.gutierrez@amd.com    class CUExitCallback : public Callback
37911308Santhony.gutierrez@amd.com    {
38011308Santhony.gutierrez@amd.com      private:
38111308Santhony.gutierrez@amd.com        ComputeUnit *computeUnit;
38211308Santhony.gutierrez@amd.com
38311308Santhony.gutierrez@amd.com      public:
38411308Santhony.gutierrez@amd.com        virtual ~CUExitCallback() { }
38511308Santhony.gutierrez@amd.com
38611308Santhony.gutierrez@amd.com        CUExitCallback(ComputeUnit *_cu)
38711308Santhony.gutierrez@amd.com        {
38811308Santhony.gutierrez@amd.com            computeUnit = _cu;
38911308Santhony.gutierrez@amd.com        }
39011308Santhony.gutierrez@amd.com
39111308Santhony.gutierrez@amd.com        virtual void
39211308Santhony.gutierrez@amd.com        process();
39311308Santhony.gutierrez@amd.com    };
39411308Santhony.gutierrez@amd.com
39511308Santhony.gutierrez@amd.com    CUExitCallback *cuExitCallback;
39611308Santhony.gutierrez@amd.com
39711308Santhony.gutierrez@amd.com    /** Data access Port **/
39811308Santhony.gutierrez@amd.com    class DataPort : public MasterPort
39911308Santhony.gutierrez@amd.com    {
40011308Santhony.gutierrez@amd.com      public:
40111308Santhony.gutierrez@amd.com        DataPort(const std::string &_name, ComputeUnit *_cu, PortID _index)
40211308Santhony.gutierrez@amd.com            : MasterPort(_name, _cu), computeUnit(_cu),
40311308Santhony.gutierrez@amd.com              index(_index) { }
40411308Santhony.gutierrez@amd.com
40511308Santhony.gutierrez@amd.com        bool snoopRangeSent;
40611308Santhony.gutierrez@amd.com
40711308Santhony.gutierrez@amd.com        struct SenderState : public Packet::SenderState
40811308Santhony.gutierrez@amd.com        {
40911308Santhony.gutierrez@amd.com            GPUDynInstPtr _gpuDynInst;
41011308Santhony.gutierrez@amd.com            int port_index;
41111308Santhony.gutierrez@amd.com            Packet::SenderState *saved;
41211308Santhony.gutierrez@amd.com
41311308Santhony.gutierrez@amd.com            SenderState(GPUDynInstPtr gpuDynInst, PortID _port_index,
41411308Santhony.gutierrez@amd.com                        Packet::SenderState *sender_state=nullptr)
41511308Santhony.gutierrez@amd.com                : _gpuDynInst(gpuDynInst),
41611308Santhony.gutierrez@amd.com                  port_index(_port_index),
41711308Santhony.gutierrez@amd.com                  saved(sender_state) { }
41811308Santhony.gutierrez@amd.com        };
41911308Santhony.gutierrez@amd.com
42011308Santhony.gutierrez@amd.com        class MemReqEvent : public Event
42111308Santhony.gutierrez@amd.com        {
42211308Santhony.gutierrez@amd.com          private:
42311308Santhony.gutierrez@amd.com            DataPort *dataPort;
42411308Santhony.gutierrez@amd.com            PacketPtr pkt;
42511308Santhony.gutierrez@amd.com
42611308Santhony.gutierrez@amd.com          public:
42711308Santhony.gutierrez@amd.com            MemReqEvent(DataPort *_data_port, PacketPtr _pkt)
42811308Santhony.gutierrez@amd.com                : Event(), dataPort(_data_port), pkt(_pkt)
42911308Santhony.gutierrez@amd.com            {
43011308Santhony.gutierrez@amd.com              setFlags(Event::AutoDelete);
43111308Santhony.gutierrez@amd.com            }
43211308Santhony.gutierrez@amd.com
43311308Santhony.gutierrez@amd.com            void process();
43411308Santhony.gutierrez@amd.com            const char *description() const;
43511308Santhony.gutierrez@amd.com        };
43611308Santhony.gutierrez@amd.com
43711308Santhony.gutierrez@amd.com        class MemRespEvent : public Event
43811308Santhony.gutierrez@amd.com        {
43911308Santhony.gutierrez@amd.com          private:
44011308Santhony.gutierrez@amd.com            DataPort *dataPort;
44111308Santhony.gutierrez@amd.com            PacketPtr pkt;
44211308Santhony.gutierrez@amd.com
44311308Santhony.gutierrez@amd.com          public:
44411308Santhony.gutierrez@amd.com            MemRespEvent(DataPort *_data_port, PacketPtr _pkt)
44511308Santhony.gutierrez@amd.com                : Event(), dataPort(_data_port), pkt(_pkt)
44611308Santhony.gutierrez@amd.com            {
44711308Santhony.gutierrez@amd.com              setFlags(Event::AutoDelete);
44811308Santhony.gutierrez@amd.com            }
44911308Santhony.gutierrez@amd.com
45011308Santhony.gutierrez@amd.com            void process();
45111308Santhony.gutierrez@amd.com            const char *description() const;
45211308Santhony.gutierrez@amd.com        };
45311308Santhony.gutierrez@amd.com
45411308Santhony.gutierrez@amd.com        std::deque<std::pair<PacketPtr, GPUDynInstPtr>> retries;
45511308Santhony.gutierrez@amd.com
45611308Santhony.gutierrez@amd.com      protected:
45711308Santhony.gutierrez@amd.com        ComputeUnit *computeUnit;
45811308Santhony.gutierrez@amd.com        int index;
45911308Santhony.gutierrez@amd.com
46011308Santhony.gutierrez@amd.com        virtual bool recvTimingResp(PacketPtr pkt);
46111308Santhony.gutierrez@amd.com        virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
46211308Santhony.gutierrez@amd.com        virtual void recvFunctional(PacketPtr pkt) { }
46311308Santhony.gutierrez@amd.com        virtual void recvRangeChange() { }
46411308Santhony.gutierrez@amd.com        virtual void recvReqRetry();
46511308Santhony.gutierrez@amd.com
46611308Santhony.gutierrez@amd.com        virtual void
46711308Santhony.gutierrez@amd.com        getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
46811308Santhony.gutierrez@amd.com        {
46911308Santhony.gutierrez@amd.com            resp.clear();
47011308Santhony.gutierrez@amd.com            snoop = true;
47111308Santhony.gutierrez@amd.com        }
47211308Santhony.gutierrez@amd.com
47311308Santhony.gutierrez@amd.com    };
47411308Santhony.gutierrez@amd.com
47511308Santhony.gutierrez@amd.com    // Instruction cache access port
47611308Santhony.gutierrez@amd.com    class SQCPort : public MasterPort
47711308Santhony.gutierrez@amd.com    {
47811308Santhony.gutierrez@amd.com      public:
47911308Santhony.gutierrez@amd.com        SQCPort(const std::string &_name, ComputeUnit *_cu, PortID _index)
48011308Santhony.gutierrez@amd.com            : MasterPort(_name, _cu), computeUnit(_cu),
48111308Santhony.gutierrez@amd.com              index(_index) { }
48211308Santhony.gutierrez@amd.com
48311308Santhony.gutierrez@amd.com        bool snoopRangeSent;
48411308Santhony.gutierrez@amd.com
48511308Santhony.gutierrez@amd.com        struct SenderState : public Packet::SenderState
48611308Santhony.gutierrez@amd.com        {
48711308Santhony.gutierrez@amd.com            Wavefront *wavefront;
48811308Santhony.gutierrez@amd.com            Packet::SenderState *saved;
48911308Santhony.gutierrez@amd.com
49011308Santhony.gutierrez@amd.com            SenderState(Wavefront *_wavefront, Packet::SenderState
49111308Santhony.gutierrez@amd.com                    *sender_state=nullptr)
49211308Santhony.gutierrez@amd.com                : wavefront(_wavefront), saved(sender_state) { }
49311308Santhony.gutierrez@amd.com        };
49411308Santhony.gutierrez@amd.com
49511308Santhony.gutierrez@amd.com        std::deque<std::pair<PacketPtr, Wavefront*>> retries;
49611308Santhony.gutierrez@amd.com
49711308Santhony.gutierrez@amd.com      protected:
49811308Santhony.gutierrez@amd.com        ComputeUnit *computeUnit;
49911308Santhony.gutierrez@amd.com        int index;
50011308Santhony.gutierrez@amd.com
50111308Santhony.gutierrez@amd.com        virtual bool recvTimingResp(PacketPtr pkt);
50211308Santhony.gutierrez@amd.com        virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
50311308Santhony.gutierrez@amd.com        virtual void recvFunctional(PacketPtr pkt) { }
50411308Santhony.gutierrez@amd.com        virtual void recvRangeChange() { }
50511308Santhony.gutierrez@amd.com        virtual void recvReqRetry();
50611308Santhony.gutierrez@amd.com
50711308Santhony.gutierrez@amd.com        virtual void
50811308Santhony.gutierrez@amd.com        getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
50911308Santhony.gutierrez@amd.com        {
51011308Santhony.gutierrez@amd.com            resp.clear();
51111308Santhony.gutierrez@amd.com            snoop = true;
51211308Santhony.gutierrez@amd.com        }
51311308Santhony.gutierrez@amd.com     };
51411308Santhony.gutierrez@amd.com
51511308Santhony.gutierrez@amd.com    /** Data TLB port **/
51611308Santhony.gutierrez@amd.com    class DTLBPort : public MasterPort
51711308Santhony.gutierrez@amd.com    {
51811308Santhony.gutierrez@amd.com      public:
51911308Santhony.gutierrez@amd.com        DTLBPort(const std::string &_name, ComputeUnit *_cu, PortID _index)
52011308Santhony.gutierrez@amd.com            : MasterPort(_name, _cu), computeUnit(_cu),
52111308Santhony.gutierrez@amd.com              index(_index), stalled(false)
52211308Santhony.gutierrez@amd.com        { }
52311308Santhony.gutierrez@amd.com
52411308Santhony.gutierrez@amd.com        bool isStalled() { return stalled; }
52511308Santhony.gutierrez@amd.com        void stallPort() { stalled = true; }
52611308Santhony.gutierrez@amd.com        void unstallPort() { stalled = false; }
52711308Santhony.gutierrez@amd.com
52811308Santhony.gutierrez@amd.com        /**
52911308Santhony.gutierrez@amd.com         * here we queue all the translation requests that were
53011308Santhony.gutierrez@amd.com         * not successfully sent.
53111308Santhony.gutierrez@amd.com         */
53211308Santhony.gutierrez@amd.com        std::deque<PacketPtr> retries;
53311308Santhony.gutierrez@amd.com
53411308Santhony.gutierrez@amd.com        /** SenderState is information carried along with the packet
53511308Santhony.gutierrez@amd.com         * throughout the TLB hierarchy
53611308Santhony.gutierrez@amd.com         */
53711308Santhony.gutierrez@amd.com        struct SenderState: public Packet::SenderState
53811308Santhony.gutierrez@amd.com        {
53911308Santhony.gutierrez@amd.com            // the memInst that this is associated with
54011308Santhony.gutierrez@amd.com            GPUDynInstPtr _gpuDynInst;
54111308Santhony.gutierrez@amd.com
54211308Santhony.gutierrez@amd.com            // the lane in the memInst this is associated with, so we send
54311308Santhony.gutierrez@amd.com            // the memory request down the right port
54411308Santhony.gutierrez@amd.com            int portIndex;
54511308Santhony.gutierrez@amd.com
54611308Santhony.gutierrez@amd.com            // constructor used for packets involved in timing accesses
54711308Santhony.gutierrez@amd.com            SenderState(GPUDynInstPtr gpuDynInst, PortID port_index)
54811308Santhony.gutierrez@amd.com                : _gpuDynInst(gpuDynInst), portIndex(port_index) { }
54911308Santhony.gutierrez@amd.com
55011308Santhony.gutierrez@amd.com        };
55111308Santhony.gutierrez@amd.com
55211308Santhony.gutierrez@amd.com      protected:
55311308Santhony.gutierrez@amd.com        ComputeUnit *computeUnit;
55411308Santhony.gutierrez@amd.com        int index;
55511308Santhony.gutierrez@amd.com        bool stalled;
55611308Santhony.gutierrez@amd.com
55711308Santhony.gutierrez@amd.com        virtual bool recvTimingResp(PacketPtr pkt);
55811308Santhony.gutierrez@amd.com        virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
55911308Santhony.gutierrez@amd.com        virtual void recvFunctional(PacketPtr pkt) { }
56011308Santhony.gutierrez@amd.com        virtual void recvRangeChange() { }
56111308Santhony.gutierrez@amd.com        virtual void recvReqRetry();
56211308Santhony.gutierrez@amd.com    };
56311308Santhony.gutierrez@amd.com
56411308Santhony.gutierrez@amd.com    class ITLBPort : public MasterPort
56511308Santhony.gutierrez@amd.com    {
56611308Santhony.gutierrez@amd.com      public:
56711308Santhony.gutierrez@amd.com        ITLBPort(const std::string &_name, ComputeUnit *_cu)
56811308Santhony.gutierrez@amd.com            : MasterPort(_name, _cu), computeUnit(_cu), stalled(false) { }
56911308Santhony.gutierrez@amd.com
57011308Santhony.gutierrez@amd.com
57111308Santhony.gutierrez@amd.com        bool isStalled() { return stalled; }
57211308Santhony.gutierrez@amd.com        void stallPort() { stalled = true; }
57311308Santhony.gutierrez@amd.com        void unstallPort() { stalled = false; }
57411308Santhony.gutierrez@amd.com
57511308Santhony.gutierrez@amd.com        /**
57611308Santhony.gutierrez@amd.com         * here we queue all the translation requests that were
57711308Santhony.gutierrez@amd.com         * not successfully sent.
57811308Santhony.gutierrez@amd.com         */
57911308Santhony.gutierrez@amd.com        std::deque<PacketPtr> retries;
58011308Santhony.gutierrez@amd.com
58111308Santhony.gutierrez@amd.com        /** SenderState is information carried along with the packet
58211308Santhony.gutierrez@amd.com         * throughout the TLB hierarchy
58311308Santhony.gutierrez@amd.com         */
58411308Santhony.gutierrez@amd.com        struct SenderState: public Packet::SenderState
58511308Santhony.gutierrez@amd.com        {
58611308Santhony.gutierrez@amd.com            // The wavefront associated with this request
58711308Santhony.gutierrez@amd.com            Wavefront *wavefront;
58811308Santhony.gutierrez@amd.com
58911308Santhony.gutierrez@amd.com            SenderState(Wavefront *_wavefront) : wavefront(_wavefront) { }
59011308Santhony.gutierrez@amd.com        };
59111308Santhony.gutierrez@amd.com
59211308Santhony.gutierrez@amd.com      protected:
59311308Santhony.gutierrez@amd.com        ComputeUnit *computeUnit;
59411308Santhony.gutierrez@amd.com        bool stalled;
59511308Santhony.gutierrez@amd.com
59611308Santhony.gutierrez@amd.com        virtual bool recvTimingResp(PacketPtr pkt);
59711308Santhony.gutierrez@amd.com        virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
59811308Santhony.gutierrez@amd.com        virtual void recvFunctional(PacketPtr pkt) { }
59911308Santhony.gutierrez@amd.com        virtual void recvRangeChange() { }
60011308Santhony.gutierrez@amd.com        virtual void recvReqRetry();
60111308Santhony.gutierrez@amd.com    };
60211308Santhony.gutierrez@amd.com
60311308Santhony.gutierrez@amd.com    /**
60411308Santhony.gutierrez@amd.com     * the port intended to communicate between the CU and its LDS
60511308Santhony.gutierrez@amd.com     */
60611308Santhony.gutierrez@amd.com    class LDSPort : public MasterPort
60711308Santhony.gutierrez@amd.com    {
60811308Santhony.gutierrez@amd.com      public:
60911308Santhony.gutierrez@amd.com        LDSPort(const std::string &_name, ComputeUnit *_cu, PortID _id)
61011308Santhony.gutierrez@amd.com        : MasterPort(_name, _cu, _id), computeUnit(_cu)
61111308Santhony.gutierrez@amd.com        {
61211308Santhony.gutierrez@amd.com        }
61311308Santhony.gutierrez@amd.com
61411308Santhony.gutierrez@amd.com        bool isStalled() const { return stalled; }
61511308Santhony.gutierrez@amd.com        void stallPort() { stalled = true; }
61611308Santhony.gutierrez@amd.com        void unstallPort() { stalled = false; }
61711308Santhony.gutierrez@amd.com
61811308Santhony.gutierrez@amd.com        /**
61911308Santhony.gutierrez@amd.com         * here we queue all the requests that were
62011308Santhony.gutierrez@amd.com         * not successfully sent.
62111308Santhony.gutierrez@amd.com         */
62211308Santhony.gutierrez@amd.com        std::queue<PacketPtr> retries;
62311308Santhony.gutierrez@amd.com
62411308Santhony.gutierrez@amd.com        /**
62511308Santhony.gutierrez@amd.com         *  SenderState is information carried along with the packet, esp. the
62611308Santhony.gutierrez@amd.com         *  GPUDynInstPtr
62711308Santhony.gutierrez@amd.com         */
62811308Santhony.gutierrez@amd.com        class SenderState: public Packet::SenderState
62911308Santhony.gutierrez@amd.com        {
63011308Santhony.gutierrez@amd.com          protected:
63111308Santhony.gutierrez@amd.com            // The actual read/write/atomic request that goes with this command
63211308Santhony.gutierrez@amd.com            GPUDynInstPtr _gpuDynInst = nullptr;
63311308Santhony.gutierrez@amd.com
63411308Santhony.gutierrez@amd.com          public:
63511308Santhony.gutierrez@amd.com            SenderState(GPUDynInstPtr gpuDynInst):
63611308Santhony.gutierrez@amd.com              _gpuDynInst(gpuDynInst)
63711308Santhony.gutierrez@amd.com            {
63811308Santhony.gutierrez@amd.com            }
63911308Santhony.gutierrez@amd.com
64011308Santhony.gutierrez@amd.com            GPUDynInstPtr
64111308Santhony.gutierrez@amd.com            getMemInst() const
64211308Santhony.gutierrez@amd.com            {
64311308Santhony.gutierrez@amd.com              return _gpuDynInst;
64411308Santhony.gutierrez@amd.com            }
64511308Santhony.gutierrez@amd.com        };
64611308Santhony.gutierrez@amd.com
64711308Santhony.gutierrez@amd.com        virtual bool
64811308Santhony.gutierrez@amd.com        sendTimingReq(PacketPtr pkt);
64911308Santhony.gutierrez@amd.com
65011308Santhony.gutierrez@amd.com      protected:
65111308Santhony.gutierrez@amd.com
65211308Santhony.gutierrez@amd.com        bool stalled = false; ///< whether or not it is stalled
65311308Santhony.gutierrez@amd.com
65411308Santhony.gutierrez@amd.com        ComputeUnit *computeUnit;
65511308Santhony.gutierrez@amd.com
65611308Santhony.gutierrez@amd.com        virtual bool
65711308Santhony.gutierrez@amd.com        recvTimingResp(PacketPtr pkt);
65811308Santhony.gutierrez@amd.com
65911308Santhony.gutierrez@amd.com        virtual Tick
66011308Santhony.gutierrez@amd.com        recvAtomic(PacketPtr pkt) { return 0; }
66111308Santhony.gutierrez@amd.com
66211308Santhony.gutierrez@amd.com        virtual void
66311308Santhony.gutierrez@amd.com        recvFunctional(PacketPtr pkt)
66411308Santhony.gutierrez@amd.com        {
66511308Santhony.gutierrez@amd.com        }
66611308Santhony.gutierrez@amd.com
66711308Santhony.gutierrez@amd.com        virtual void
66811308Santhony.gutierrez@amd.com        recvRangeChange()
66911308Santhony.gutierrez@amd.com        {
67011308Santhony.gutierrez@amd.com        }
67111308Santhony.gutierrez@amd.com
67211308Santhony.gutierrez@amd.com        virtual void
67311308Santhony.gutierrez@amd.com        recvReqRetry();
67411308Santhony.gutierrez@amd.com    };
67511308Santhony.gutierrez@amd.com
67611308Santhony.gutierrez@amd.com    /** The port to access the Local Data Store
67711308Santhony.gutierrez@amd.com     *  Can be connected to a LDS object
67811308Santhony.gutierrez@amd.com     */
67911308Santhony.gutierrez@amd.com    LDSPort *ldsPort = nullptr;
68011308Santhony.gutierrez@amd.com
68111308Santhony.gutierrez@amd.com    LDSPort *
68211308Santhony.gutierrez@amd.com    getLdsPort() const
68311308Santhony.gutierrez@amd.com    {
68411308Santhony.gutierrez@amd.com        return ldsPort;
68511308Santhony.gutierrez@amd.com    }
68611308Santhony.gutierrez@amd.com
68711308Santhony.gutierrez@amd.com    /** The memory port for SIMD data accesses.
68811308Santhony.gutierrez@amd.com     *  Can be connected to PhysMem for Ruby for timing simulations
68911308Santhony.gutierrez@amd.com     */
69011308Santhony.gutierrez@amd.com    std::vector<DataPort*> memPort;
69111308Santhony.gutierrez@amd.com    // port to the TLB hierarchy (i.e., the L1 TLB)
69211308Santhony.gutierrez@amd.com    std::vector<DTLBPort*> tlbPort;
69311308Santhony.gutierrez@amd.com    // port to the SQC (i.e. the I-cache)
69411308Santhony.gutierrez@amd.com    SQCPort *sqcPort;
69511308Santhony.gutierrez@amd.com    // port to the SQC TLB (there's a separate TLB for each I-cache)
69611308Santhony.gutierrez@amd.com    ITLBPort *sqcTLBPort;
69711308Santhony.gutierrez@amd.com
69811308Santhony.gutierrez@amd.com    virtual BaseMasterPort&
69911308Santhony.gutierrez@amd.com    getMasterPort(const std::string &if_name, PortID idx)
70011308Santhony.gutierrez@amd.com    {
70111308Santhony.gutierrez@amd.com        if (if_name == "memory_port") {
70211308Santhony.gutierrez@amd.com            memPort[idx] = new DataPort(csprintf("%s-port%d", name(), idx),
70311308Santhony.gutierrez@amd.com                                        this, idx);
70411308Santhony.gutierrez@amd.com            return *memPort[idx];
70511308Santhony.gutierrez@amd.com        } else if (if_name == "translation_port") {
70611308Santhony.gutierrez@amd.com            tlbPort[idx] = new DTLBPort(csprintf("%s-port%d", name(), idx),
70711308Santhony.gutierrez@amd.com                                        this, idx);
70811308Santhony.gutierrez@amd.com            return *tlbPort[idx];
70911308Santhony.gutierrez@amd.com        } else if (if_name == "sqc_port") {
71011308Santhony.gutierrez@amd.com            sqcPort = new SQCPort(csprintf("%s-port%d", name(), idx),
71111308Santhony.gutierrez@amd.com                                  this, idx);
71211308Santhony.gutierrez@amd.com            return *sqcPort;
71311308Santhony.gutierrez@amd.com        } else if (if_name == "sqc_tlb_port") {
71411308Santhony.gutierrez@amd.com            sqcTLBPort = new ITLBPort(csprintf("%s-port", name()), this);
71511308Santhony.gutierrez@amd.com            return *sqcTLBPort;
71611308Santhony.gutierrez@amd.com        } else if (if_name == "ldsPort") {
71711308Santhony.gutierrez@amd.com            if (ldsPort) {
71811308Santhony.gutierrez@amd.com                fatal("an LDS port was already allocated");
71911308Santhony.gutierrez@amd.com            }
72011308Santhony.gutierrez@amd.com            ldsPort = new LDSPort(csprintf("%s-port", name()), this, idx);
72111308Santhony.gutierrez@amd.com            return *ldsPort;
72211308Santhony.gutierrez@amd.com        } else {
72311308Santhony.gutierrez@amd.com            panic("incorrect port name");
72411308Santhony.gutierrez@amd.com        }
72511308Santhony.gutierrez@amd.com    }
72611308Santhony.gutierrez@amd.com
72711308Santhony.gutierrez@amd.com    // xact_cas_load()
72811308Santhony.gutierrez@amd.com    class waveIdentifier
72911308Santhony.gutierrez@amd.com    {
73011308Santhony.gutierrez@amd.com      public:
73111308Santhony.gutierrez@amd.com        waveIdentifier() { }
73211308Santhony.gutierrez@amd.com        waveIdentifier(int _simdId, int _wfSlotId)
73311308Santhony.gutierrez@amd.com          : simdId(_simdId), wfSlotId(_wfSlotId) { }
73411308Santhony.gutierrez@amd.com
73511308Santhony.gutierrez@amd.com        int simdId;
73611308Santhony.gutierrez@amd.com        int wfSlotId;
73711308Santhony.gutierrez@amd.com    };
73811308Santhony.gutierrez@amd.com
73911308Santhony.gutierrez@amd.com    class waveQueue
74011308Santhony.gutierrez@amd.com    {
74111308Santhony.gutierrez@amd.com      public:
74211308Santhony.gutierrez@amd.com        std::list<waveIdentifier> waveIDQueue;
74311308Santhony.gutierrez@amd.com    };
74411308Santhony.gutierrez@amd.com    std::map<unsigned, waveQueue> xactCasLoadMap;
74511308Santhony.gutierrez@amd.com
74611308Santhony.gutierrez@amd.com    uint64_t getAndIncSeqNum() { return globalSeqNum++; }
74711308Santhony.gutierrez@amd.com
74811308Santhony.gutierrez@amd.com  private:
74911308Santhony.gutierrez@amd.com    uint64_t globalSeqNum;
75011308Santhony.gutierrez@amd.com    int wavefrontSize;
75111308Santhony.gutierrez@amd.com};
75211308Santhony.gutierrez@amd.com
75311308Santhony.gutierrez@amd.com#endif // __COMPUTE_UNIT_HH__
754