/*
 * Copyright (c) 2014-2015 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * 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.
 */

#include "gpu-compute/scoreboard_check_stage.hh"

#include "debug/GPUExec.hh"
#include "debug/GPUSched.hh"
#include "debug/GPUSync.hh"
#include "gpu-compute/compute_unit.hh"
#include "gpu-compute/gpu_static_inst.hh"
#include "gpu-compute/scalar_register_file.hh"
#include "gpu-compute/shader.hh"
#include "gpu-compute/vector_register_file.hh"
#include "gpu-compute/wavefront.hh"
#include "params/ComputeUnit.hh"

namespace gem5
{

ScoreboardCheckStage::ScoreboardCheckStage(const ComputeUnitParams &p,
                                           ComputeUnit &cu,
                                           ScoreboardCheckToSchedule
                                           &to_schedule)
    : computeUnit(cu), toSchedule(to_schedule),
      _name(cu.name() + ".ScoreboardCheckStage"), stats(&cu)
{
}

ScoreboardCheckStage::~ScoreboardCheckStage()
{
}

void
ScoreboardCheckStage::collectStatistics(nonrdytype_e rdyStatus)
{
    panic_if(rdyStatus == NRDY_ILLEGAL || rdyStatus >= NRDY_CONDITIONS,
             "Instruction ready status %d is illegal!!!", rdyStatus);
    stats.stallCycles[rdyStatus]++;
}

// Return true if this wavefront is ready
// to execute an instruction of the specified type.
// It also returns the reason (in rdyStatus) if the instruction is not
// ready. Finally it sets the execution resource type (in exesResType)
// of the instruction, only if it ready.
bool
ScoreboardCheckStage::ready(Wavefront *w, nonrdytype_e *rdyStatus,
                            int *exeResType, int wfSlot)
{
    /**
     * The waitCnt checks have to be done BEFORE checking for Instruction
     * buffer empty condition. Otherwise, it will result into a deadlock if
     * the last instruction in the Instruction buffer is a waitCnt: after
     * executing the waitCnt, the Instruction buffer would be empty and the
     * ready check logic will exit BEFORE checking for wait counters being
     * satisfied.
     */

    // waitCnt instruction has been dispatched or executed: next
    // instruction should be blocked until waitCnts are satisfied.
    if (w->getStatus() == Wavefront::S_WAITCNT) {
        if (!w->waitCntsSatisfied()) {
            *rdyStatus = NRDY_WAIT_CNT;
            return false;
        }
    }

    // sleep instruction has been dispatched or executed: next
    // instruction should be blocked until the sleep period expires.
    if (w->getStatus() == Wavefront::S_STALLED_SLEEP) {
        if (!w->sleepDone()) {
            *rdyStatus = NRDY_SLEEP;
            return false;
        }
    }

    // Is the wave waiting at a barrier. Check this condition BEFORE checking
    // for instruction buffer occupancy to avoid a deadlock when the barrier is
    // the last instruction in the instruction buffer.
    if (w->getStatus() == Wavefront::S_BARRIER) {
        assert(w->hasBarrier());
        int bar_id = w->barrierId();
        if (!computeUnit.allAtBarrier(bar_id)) {
            DPRINTF(GPUSync, "CU[%d] WF[%d][%d] Wave[%d] - Stalled at "
                    "barrier Id%d. %d waves remain.\n", w->computeUnit->cu_id,
                    w->simdId, w->wfSlotId, w->wfDynId, bar_id,
                    w->computeUnit->numYetToReachBarrier(bar_id));
            // Are all threads at barrier?
            *rdyStatus = NRDY_BARRIER_WAIT;
            return false;
        }
        DPRINTF(GPUSync, "CU[%d] WF[%d][%d] Wave[%d] - All waves at barrier "
                "Id%d. Resetting barrier resources.\n", w->computeUnit->cu_id,
                w->simdId, w->wfSlotId, w->wfDynId, bar_id);
        computeUnit.resetBarrier(bar_id);
        computeUnit.releaseWFsFromBarrier(bar_id);
    }

    // Check WF status: it has to be running
    if (w->getStatus() == Wavefront::S_STOPPED ||
        w->getStatus() == Wavefront::S_RETURNING ||
        w->getStatus() == Wavefront::S_STALLED) {
        *rdyStatus = NRDY_WF_STOP;
        return false;
    }

    // is the Instruction buffer empty
    if ( w->instructionBuffer.empty()) {
        *rdyStatus = NRDY_IB_EMPTY;
        return false;
    }

    // Check next instruction from instruction buffer
    GPUDynInstPtr ii = w->nextInstr();
    // Only instruction in the instruction buffer has been dispatched.
    // No need to check it again for readiness
    if (!ii) {
        *rdyStatus = NRDY_IB_EMPTY;
        return false;
    }

    // The following code is very error prone and the entire process for
    // checking readiness will be fixed eventually.  In the meantime, let's
    // make sure that we do not silently let an instruction type slip
    // through this logic and always return not ready.
    if (!(ii->isBarrier() || ii->isNop() || ii->isReturn() || ii->isBranch() ||
         ii->isALU() || ii->isLoad() || ii->isStore() || ii->isAtomic() ||
         ii->isEndOfKernel() || ii->isMemSync() || ii->isFlat() ||
         ii->isFlatGlobal() || ii->isSleep())) {
        panic("next instruction: %s is of unknown type\n", ii->disassemble());
    }

    DPRINTF(GPUExec, "CU%d: WF[%d][%d]: Checking Ready for Inst : %s\n",
            computeUnit.cu_id, w->simdId, w->wfSlotId, ii->disassemble());

    // Non-scalar (i.e., vector) instructions may use VGPRs
    if (!ii->isScalar()) {
        if (!computeUnit.vrf[w->simdId]->operandsReady(w, ii)) {
            *rdyStatus = NRDY_VGPR_NRDY;
            return false;
        }
    }
    // Scalar and non-scalar instructions may use SGPR
    if (!computeUnit.srf[w->simdId]->operandsReady(w, ii)) {
        *rdyStatus = NRDY_SGPR_NRDY;
        return false;
    }

    // The hardware implicitly executes S_WAITCNT 0 before executing
    // the S_ENDPGM instruction. Implementing this implicit S_WAITCNT.
    // isEndOfKernel() is used to identify the S_ENDPGM instruction
    // On identifying it, we do the following:
    // 1. Wait for all older instruction to execute
    // 2. Once all the older instruction are executed, we add a wait
    //    count for the executed instruction(s) to complete.
    if (ii->isEndOfKernel()) {
        // Waiting for older instruction to execute
        if (w->instructionBuffer.front()->seqNum() != ii->seqNum()) {
            *rdyStatus = NRDY_WAIT_CNT;
            return false;
        }
        // Older instructions have executed, adding implicit wait count
        w->setStatus(Wavefront::S_WAITCNT);
        w->setWaitCnts(0, 0, 0);
        if (!w->waitCntsSatisfied()) {
            *rdyStatus = NRDY_WAIT_CNT;
            return false;
        }
    }
    DPRINTF(GPUExec, "CU%d: WF[%d][%d]: Ready Inst : %s\n", computeUnit.cu_id,
            w->simdId, w->wfSlotId, ii->disassemble());
    *exeResType = mapWaveToExeUnit(w);
    *rdyStatus = INST_RDY;
    return true;
}

int
ScoreboardCheckStage::mapWaveToExeUnit(Wavefront *w)
{
    GPUDynInstPtr ii = w->nextInstr();
    assert(ii);
    if (ii->isFlat()) {
        /**
         * NOTE: Flat memory ops requires both GM and LM resources.
         * The simulator models consumption of both GM and LM
         * resources in the schedule stage. At instruction execution time,
         * after the aperture check is performed, only the GM or LM pipe
         * is actually reserved by the timing model. The GM unit is returned
         * here since Flat ops occupy the GM slot in the ready and dispatch
         * lists. They also consume the LM slot in the dispatch list.
         */
        return w->globalMem;
    } else if (ii->isLocalMem()) {
        return w->localMem;
    } else if (ii->isGlobalMem()) {
        if (!ii->isScalar()) {
            return w->globalMem;
        } else {
            return w->scalarMem;
        }
    } else if (ii->isBranch() ||
               ii->isALU() ||
               (ii->isKernArgSeg() && ii->isLoad()) ||
               ii->isArgSeg() ||
               ii->isReturn() ||
               ii->isEndOfKernel() ||
               ii->isNop() ||
               ii->isBarrier()) {
        if (!ii->isScalar()) {
            return w->simdId;
        } else {
            return w->scalarAluGlobalIdx;
        }
    }
    panic("%s: unmapped to an execution resource", ii->disassemble());
    return computeUnit.numExeUnits();
}

void
ScoreboardCheckStage::exec()
{
    /**
     * Reset the ready list for all execution units; ready list will be
     * constructed every cycle because resource availability may change.
     */
    toSchedule.reset();

    // Iterate over all WF slots across all SIMDs.
    for (int simdId = 0; simdId < computeUnit.numVectorALUs; ++simdId) {
        for (int wfSlot = 0; wfSlot < computeUnit.shader->n_wf; ++wfSlot) {
            // reset the ready status of each wavefront
            Wavefront *curWave = computeUnit.wfList[simdId][wfSlot];
            nonrdytype_e rdyStatus = NRDY_ILLEGAL;
            int exeResType = -1;
            // check WF readiness: If the WF's oldest
            // instruction is ready to issue then add the WF to the ready list
            if (ready(curWave, &rdyStatus, &exeResType, wfSlot)) {
                assert(curWave->simdId == simdId);
                DPRINTF(GPUSched,
                        "Adding to readyList[%d]: SIMD[%d] WV[%d]: %d: %s\n",
                        exeResType,
                        curWave->simdId, curWave->wfDynId,
                        curWave->nextInstr()->seqNum(),
                        curWave->nextInstr()->disassemble());
                toSchedule.markWFReady(curWave, exeResType);
            }
            collectStatistics(rdyStatus);
        }
    }
}

ScoreboardCheckStage::
ScoreboardCheckStageStats::ScoreboardCheckStageStats(statistics::Group *parent)
    : statistics::Group(parent, "ScoreboardCheckStage"),
      ADD_STAT(stallCycles, "number of cycles wave stalled in SCB")
{
    stallCycles.init(NRDY_CONDITIONS);

    stallCycles.subname(NRDY_WF_STOP, csprintf("WFStop"));
    stallCycles.subname(NRDY_IB_EMPTY, csprintf("IBEmpty"));
    stallCycles.subname(NRDY_WAIT_CNT, csprintf("WaitCnt"));
    stallCycles.subname(NRDY_BARRIER_WAIT, csprintf("BarrierWait"));
    stallCycles.subname(NRDY_VGPR_NRDY, csprintf("VgprBusy"));
    stallCycles.subname(NRDY_SGPR_NRDY, csprintf("SgprBusy"));
    stallCycles.subname(INST_RDY, csprintf("InstrReady"));
}

} // namespace gem5
