/*
 * 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/lds_state.hh"

#include <array>
#include <cstdio>
#include <cstdlib>

#include "gpu-compute/compute_unit.hh"
#include "gpu-compute/gpu_dyn_inst.hh"
#include "gpu-compute/shader.hh"

namespace gem5
{

/**
 * the default constructor that works with SWIG
 */
LdsState::LdsState(const Params &params) :
    ClockedObject(params),
    tickEvent(this),
    cuPort(name() + ".port", this),
    maximumSize(params.size),
    range(params.range),
    bankConflictPenalty(params.bankConflictPenalty),
    banks(params.banks)
{
    fatal_if(params.banks <= 0,
             "Number of LDS banks should be positive number");
    fatal_if((params.banks & (params.banks - 1)) != 0,
             "Number of LDS banks should be a power of 2");
    fatal_if(params.size <= 0,
             "cannot allocate an LDS with a size less than 1");
    fatal_if(params.size % 2,
          "the LDS should be an even number");
}

/**
 * set the parent and name based on the parent
 */
void
LdsState::setParent(ComputeUnit *x_parent)
{
    // check that this gets assigned to the same thing each time
    fatal_if(!x_parent, "x_parent should not be nullptr");
    fatal_if(x_parent == parent,
             "should not be setting the parent twice");

    parent = x_parent;
    _name = x_parent->name() + ".LdsState";
}

/**
 * derive the gpu mem packet from the packet and then count the bank conflicts
 */
unsigned
LdsState::countBankConflicts(PacketPtr packet, unsigned *bankAccesses)
{
    Packet::SenderState *baseSenderState = packet->senderState;
    while (baseSenderState->predecessor) {
        baseSenderState = baseSenderState->predecessor;
    }
    const ComputeUnit::LDSPort::SenderState *senderState =
            dynamic_cast<ComputeUnit::LDSPort::SenderState *>(baseSenderState);

    fatal_if(!senderState,
             "did not get the right sort of sender state");

    GPUDynInstPtr gpuDynInst = senderState->getMemInst();

    return countBankConflicts(gpuDynInst, bankAccesses);
}

// Count the total number of bank conflicts for the local memory packet
unsigned
LdsState::countBankConflicts(GPUDynInstPtr gpuDynInst,
                             unsigned *numBankAccesses)
{
    int bank_conflicts = 0;
    std::vector<int> bank;
    // the number of LDS banks being touched by the memory instruction
    int numBanks = std::min(parent->wfSize(), banks);
    // if the wavefront size is larger than the number of LDS banks, we
    // need to iterate over all work items to calculate the total
    // number of bank conflicts
    int groups = (parent->wfSize() > numBanks) ?
        (parent->wfSize() / numBanks) : 1;
    for (int i = 0; i < groups; i++) {
        // Address Array holding all the work item addresses of an instruction
        std::vector<Addr> addr_array;
        addr_array.resize(numBanks, 0);
        bank.clear();
        bank.resize(banks, 0);
        int max_bank = 0;

        // populate the address array for all active work items
        for (int j = 0; j < numBanks; j++) {
            if (gpuDynInst->exec_mask[(i*numBanks)+j]) {
                addr_array[j] = gpuDynInst->addr[(i*numBanks)+j];
            } else {
                addr_array[j] = std::numeric_limits<Addr>::max();
            }
        }

        if (gpuDynInst->isLoad() || gpuDynInst->isStore()) {
            // mask identical addresses
            for (int j = 0; j < numBanks; ++j) {
                for (int j0 = 0; j0 < j; j0++) {
                    if (addr_array[j] != std::numeric_limits<Addr>::max()
                                    && addr_array[j] == addr_array[j0]) {
                        addr_array[j] = std::numeric_limits<Addr>::max();
                    }
                }
            }
        }
        // calculate bank conflicts
        for (int j = 0; j < numBanks; ++j) {
            if (addr_array[j] != std::numeric_limits<Addr>::max()) {
                int bankId = addr_array[j] % banks;
                bank[bankId]++;
                max_bank = std::max(max_bank, bank[bankId]);
                // Count the number of LDS banks accessed.
                // Since we have masked identical addresses all remaining
                // accesses will need to be serialized if they access
                // the same bank (bank conflict).
                (*numBankAccesses)++;
            }
        }
        bank_conflicts += max_bank;
    }
    panic_if(bank_conflicts > parent->wfSize(),
             "Max bank conflicts should match num of work items per instr");
    return bank_conflicts;
}

/**
 * receive the packet from the CU
 */
bool
LdsState::CuSidePort::recvTimingReq(PacketPtr packet)
{
    return ownerLds->processPacket(packet);
}

GPUDynInstPtr
LdsState::getDynInstr(PacketPtr packet)
{
    ComputeUnit::LDSPort::SenderState *ss =
        dynamic_cast<ComputeUnit::LDSPort::SenderState *>(
                     packet->senderState);
    return ss->getMemInst();
}

/**
 * process an incoming packet, add it to the return queue
 */
bool
LdsState::processPacket(PacketPtr packet)
{
    unsigned bankAccesses = 0;
    // the number of conflicts this packet will have when accessing the LDS
    unsigned bankConflicts = countBankConflicts(packet, &bankAccesses);
    // count the total number of physical LDS bank accessed
    parent->stats.ldsBankAccesses += bankAccesses;
    // count the LDS bank conflicts. A number set to 1 indicates one
    // access per bank maximum so there are no bank conflicts
    parent->stats.ldsBankConflictDist.sample(bankConflicts-1);

    GPUDynInstPtr dynInst = getDynInstr(packet);
    // account for the LDS bank conflict overhead
    int busLength = (dynInst->isLoad()) ? parent->loadBusLength() :
        (dynInst->isStore()) ? parent->storeBusLength() :
        parent->loadBusLength();
    // delay for accessing the LDS
    Tick processingTime =
        parent->cyclesToTicks(Cycles(bankConflicts * bankConflictPenalty)) +
        parent->cyclesToTicks(Cycles(busLength));
    // choose (delay + last packet in queue) or (now + delay) as the time to
    // return this
    Tick doneAt = earliestReturnTime() + processingTime;
    // then store it for processing
    return returnQueuePush(std::make_pair(doneAt, packet));
}

/**
 * add this to the queue of packets to be returned
 */
bool
LdsState::returnQueuePush(std::pair<Tick, PacketPtr> thePair)
{
    // TODO add time limits (e.g. one packet per cycle) and queue size limits
    // and implement flow control
    returnQueue.push(thePair);

    // if there is no set wakeup time, look through the queue
    if (!tickEvent.scheduled()) {
        process();
    }

    return true;
}

/**
 * receive a packet in functional mode
 */
void
LdsState::CuSidePort::recvFunctional(PacketPtr pkt)
{
    fatal("not implemented");
}

/**
 * receive a retry for a response
 */
void
LdsState::CuSidePort::recvRespRetry()
{
    // TODO verify that this is the right way to do this
    assert(ownerLds->isRetryResp());
    ownerLds->setRetryResp(false);
    ownerLds->process();
}

/**
 * receive a retry
 */
void
LdsState::CuSidePort::recvRetry()
{
    fatal("not implemented");
}

/**
 * look for packets to return at this time
 */
bool
LdsState::process()
{
    Tick now = clockEdge();

    // send back completed packets
    while (!returnQueue.empty() && returnQueue.front().first <= now) {
        PacketPtr packet = returnQueue.front().second;

        ComputeUnit::LDSPort::SenderState *ss =
            dynamic_cast<ComputeUnit::LDSPort::SenderState *>(
                            packet->senderState);

        GPUDynInstPtr gpuDynInst = ss->getMemInst();

        gpuDynInst->initiateAcc(gpuDynInst);

        packet->makeTimingResponse();

        returnQueue.pop();

        bool success = cuPort.sendTimingResp(packet);

        if (!success) {
            retryResp = true;
            panic("have not handled timing responses being NACK'd when sent"
                            "back");
        }
    }

    // determine the next wakeup time
    if (!returnQueue.empty()) {

        Tick next = returnQueue.front().first;

        if (tickEvent.scheduled()) {

            if (next < tickEvent.when()) {

                tickEvent.deschedule();
                tickEvent.schedule(next);
            }
        } else {
            tickEvent.schedule(next);
        }
    }

    return true;
}

/**
 * wake up at this time and perform specified actions
 */
void
LdsState::TickEvent::process()
{
    ldsState->process();
}

} // namespace gem5
