/*
 * 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.
 *
 * Authors: John Kalamatianos,
 *          Sooraj Puthoor,
 *          Mark Wyse
 */

#include "gpu-compute/schedule_stage.hh"

#include "gpu-compute/compute_unit.hh"
#include "gpu-compute/gpu_static_inst.hh"
#include "gpu-compute/vector_register_file.hh"
#include "gpu-compute/wavefront.hh"

ScheduleStage::ScheduleStage(const ComputeUnitParams *p)
    : numSIMDs(p->num_SIMDs),
      numMemUnits(p->num_global_mem_pipes + p->num_shared_mem_pipes)
{
    for (int j = 0; j < numSIMDs + numMemUnits; ++j) {
        scheduler.emplace_back(p);
    }
}

ScheduleStage::~ScheduleStage()
{
    scheduler.clear();
    waveStatusList.clear();
}

void
ScheduleStage::init(ComputeUnit *cu)
{
    computeUnit = cu;
    _name = computeUnit->name() + ".ScheduleStage";

    for (int j = 0; j < numSIMDs + numMemUnits; ++j) {
        scheduler[j].bindList(&computeUnit->readyList[j]);
    }

    for (int j = 0; j < numSIMDs; ++j) {
        waveStatusList.push_back(&computeUnit->waveStatusList[j]);
    }

    dispatchList = &computeUnit->dispatchList;
}

void
ScheduleStage::arbitrate()
{
    // iterate over all Memory pipelines
    for (int j = numSIMDs; j < numSIMDs + numMemUnits; ++j) {
        if (dispatchList->at(j).first) {
            Wavefront *waveToMemPipe = dispatchList->at(j).first;
            // iterate over all execution pipelines
            for (int i = 0; i < numSIMDs + numMemUnits; ++i) {
                if ((i != j) && (dispatchList->at(i).first)) {
                    Wavefront *waveToExePipe = dispatchList->at(i).first;
                    // if the two selected wavefronts are mapped to the same
                    // SIMD unit then they share the VRF
                    if (waveToMemPipe->simdId == waveToExePipe->simdId) {
                        int simdId = waveToMemPipe->simdId;
                        // Read VRF port arbitration:
                        // If there are read VRF port conflicts between the
                        // a memory and another instruction we drop the other
                        // instruction. We don't need to check for write VRF
                        // port conflicts because the memory instruction either
                        // does not need to write to the VRF (store) or will
                        // write to the VRF when the data comes back (load) in
                        // which case the arbiter of the memory pipes will
                        // resolve any conflicts
                        if (computeUnit->vrf[simdId]->
                            isReadConflict(waveToMemPipe->wfSlotId,
                            waveToExePipe->wfSlotId)) {
                            // FIXME: The "second" member variable is never
                            // used in the model. I am setting it to READY
                            // simply to follow the protocol of setting it
                            // when the WF has an instruction ready to issue
                            waveStatusList[simdId]->at(waveToExePipe->wfSlotId)
                                                    .second = READY;

                            dispatchList->at(i).first = nullptr;
                            dispatchList->at(i).second = EMPTY;
                            break;
                        }
                    }
                }
            }
        }
    }
}

void
ScheduleStage::exec()
{
    for (int j = 0; j < numSIMDs + numMemUnits; ++j) {
         uint32_t readyListSize = computeUnit->readyList[j].size();

         // If no wave is ready to be scheduled on the execution resource
         // then skip scheduling for this execution resource
         if (!readyListSize) {
             continue;
         }

         Wavefront *waveToBeDispatched = scheduler[j].chooseWave();
         dispatchList->at(j).first = waveToBeDispatched;
         waveToBeDispatched->updateResources();
         dispatchList->at(j).second = FILLED;

         waveStatusList[waveToBeDispatched->simdId]->at(
                 waveToBeDispatched->wfSlotId).second = BLOCKED;

         assert(computeUnit->readyList[j].size() == readyListSize - 1);
    }
    // arbitrate over all shared resources among instructions being issued
    // simultaneously
    arbitrate();
}

void
ScheduleStage::regStats()
{
}
