base: Add some error handling to compiler.hh.
[gem5.git] / src / gpu-compute / global_memory_pipeline.hh
index ed49f6f6bf41f1e2204d70eb3f262aedab874f89..c53789ee509865f50d95225d0f0bc29f9a1415f5 100644 (file)
@@ -14,9 +14,9 @@
  * this list of conditions and the following disclaimer in the documentation
  * and/or other materials provided with the distribution.
  *
- * 3. Neither the name of the copyright holder nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -29,8 +29,6 @@
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
- *
- * Author: John Kalamatianos, Sooraj Puthoor
  */
 
 #ifndef __GLOBAL_MEMORY_PIPELINE_HH__
@@ -58,27 +56,37 @@ class ComputeUnit;
 class GlobalMemPipeline
 {
   public:
-    GlobalMemPipeline(const ComputeUnitParams *params);
-    void init(ComputeUnit *cu);
+    GlobalMemPipeline(const ComputeUnitParams *p, ComputeUnit &cu);
+    void init();
     void exec();
 
-    template<typename c0, typename c1> void doGmReturn(GPUDynInstPtr m);
-
-    std::queue<GPUDynInstPtr> &getGMReqFIFO() { return gmIssuedRequests; }
-    std::queue<GPUDynInstPtr> &getGMStRespFIFO() { return gmReturnedStores; }
-    std::queue<GPUDynInstPtr> &getGMLdRespFIFO() { return gmReturnedLoads; }
-
-    bool
-    isGMLdRespFIFOWrRdy() const
-    {
-        return gmReturnedLoads.size() < gmQueueSize;
-    }
-
-    bool
-    isGMStRespFIFOWrRdy() const
-    {
-        return gmReturnedStores.size() < gmQueueSize;
-    }
+    /**
+     * Find the next ready response to service. In order to ensure
+     * that no waitcnts are violated, we pop the oldest (in program order)
+     * response, and only if it is marked as done. This is because waitcnt
+     * values expect memory operations to complete and decrement their
+     * counter values in program order.
+     */
+    GPUDynInstPtr getNextReadyResp();
+
+    /**
+     * once a memory request is finished we remove it from the
+     * buffer.
+     */
+    void completeRequest(GPUDynInstPtr gpuDynInst);
+
+    /**
+     * Issues a request to the pipeline (i.e., enqueue it
+     * in the request buffer).
+     */
+    void issueRequest(GPUDynInstPtr gpuDynInst);
+
+    /**
+     * This method handles responses sent to this GM pipeline by the
+     * CU. Simply marks the reqeust as done in the ordered buffer to
+     * indicate that the requst is finished.
+     */
+    void handleResponse(GPUDynInstPtr gpuDynInst);
 
     bool
     isGMReqFIFOWrRdy(uint32_t pendReqs=0) const
@@ -88,11 +96,22 @@ class GlobalMemPipeline
 
     const std::string &name() const { return _name; }
     void regStats();
+    void
+    incLoadVRFBankConflictCycles(int num_cycles)
+    {
+        loadVrfBankConflictCycles += num_cycles;
+    }
+
+    bool coalescerReady(GPUDynInstPtr mp) const;
+    bool outstandingReqsCheck(GPUDynInstPtr mp) const;
+
+    void acqCoalescerToken(GPUDynInstPtr mp);
 
   private:
-    ComputeUnit *computeUnit;
-    std::string _name;
+    ComputeUnit &computeUnit;
+    const std::string _name;
     int gmQueueSize;
+    int maxWaveRequests;
 
     // number of cycles of delaying the update of a VGPR that is the
     // target of a load instruction (or the load component of an atomic)
@@ -107,17 +126,24 @@ class GlobalMemPipeline
     // The size of global memory.
     int globalMemSize;
 
+    /*
+     * This buffer holds the memory responses in order data - the responses
+     * are ordered by their unique sequence number, which is monotonically
+     * increasing. When a memory request returns its "done" flag is set to
+     * true. During each tick the the GM pipeline will check if the oldest
+     * request is finished, and if so it will be removed from the queue.
+     *
+     * key:   memory instruction's sequence ID
+     *
+     * value: pair holding the instruction pointer and a bool that
+     *        is used to indicate whether or not the request has
+     *        completed
+     */
+    std::map<uint64_t, std::pair<GPUDynInstPtr, bool>> gmOrderedRespBuffer;
+
     // Global Memory Request FIFO: all global memory requests
     // are issued to this FIFO from the memory pipelines
     std::queue<GPUDynInstPtr> gmIssuedRequests;
-
-    // Globa Store Response FIFO: all responses of global memory
-    // stores are sent to this FIFO from TCP
-    std::queue<GPUDynInstPtr> gmReturnedStores;
-
-    // Global Load Response FIFO: all responses of global memory
-    // loads are sent to this FIFO from TCP
-    std::queue<GPUDynInstPtr> gmReturnedLoads;
 };
 
 #endif // __GLOBAL_MEMORY_PIPELINE_HH__