/*
 * Copyright (c) 2014-2015 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * 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.
 */

#ifndef __GLOBAL_MEMORY_PIPELINE_HH__
#define __GLOBAL_MEMORY_PIPELINE_HH__

#include <queue>
#include <string>

#include "base/statistics.hh"
#include "base/stats/group.hh"
#include "gpu-compute/misc.hh"
#include "params/ComputeUnit.hh"
#include "sim/stats.hh"

/*
 * @file global_memory_pipeline.hh
 *
 * The global memory pipeline issues newly created global memory packets
 * from the pipeline to DTLB. The exec() method of the memory packet issues
 * the packet to the DTLB if there is space available in the return fifo.
 * This stage also retires previously issued loads and stores that have
 * returned from the memory sub-system.
 */

namespace gem5
{

class ComputeUnit;

class GlobalMemPipeline
{
  public:
    GlobalMemPipeline(const ComputeUnitParams &p, ComputeUnit &cu);
    void init();
    void exec();

    /**
     * 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
    {
        return (gmIssuedRequests.size() + pendReqs) < gmQueueSize;
    }

    const std::string &name() const { return _name; }
    void
    incLoadVRFBankConflictCycles(int num_cycles)
    {
        stats.loadVrfBankConflictCycles += num_cycles;
    }

    bool coalescerReady(GPUDynInstPtr mp) const;
    bool outstandingReqsCheck(GPUDynInstPtr mp) const;

    void acqCoalescerToken(GPUDynInstPtr mp);

  private:
    ComputeUnit &computeUnit;
    const std::string _name;
    int gmQueueSize;
    int maxWaveRequests;

    // Counters to track the inflight loads and stores
    // so that we can provide the proper backpressure
    // on the number of inflight memory operations.
    int inflightStores;
    int inflightLoads;

    // 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;

  protected:
    struct GlobalMemPipelineStats : public statistics::Group
    {
        GlobalMemPipelineStats(statistics::Group *parent);

        // 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)
        // The delay is due to VRF bank conflicts
        statistics::Scalar loadVrfBankConflictCycles;
    } stats;
};

} // namespace gem5

#endif // __GLOBAL_MEMORY_PIPELINE_HH__
