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