/*
 * Copyright (c) 2015-2017 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,
 *          Mark Wyse
 */

#include "gpu-compute/register_file.hh"

#include <sstream>
#include <string>

#include "base/intmath.hh"
#include "base/logging.hh"
#include "debug/GPURF.hh"
#include "gpu-compute/compute_unit.hh"
#include "gpu-compute/gpu_dyn_inst.hh"
#include "gpu-compute/shader.hh"
#include "gpu-compute/wavefront.hh"
#include "params/RegisterFile.hh"

RegisterFile::RegisterFile(const RegisterFileParams *p)
    : SimObject(p), simdId(p->simd_id), _numRegs(p->num_regs)
{
    fatal_if((_numRegs % 2) != 0, "VRF size is illegal\n");
    fatal_if(simdId < 0, "Illegal SIMD id for VRF");

    busy.clear();
    busy.resize(_numRegs, 0);
}

RegisterFile::~RegisterFile()
{
}

void
RegisterFile::setParent(ComputeUnit *_computeUnit)
{
    computeUnit = _computeUnit;
}

std::string
RegisterFile::dump() const
{
    std::stringstream ss;
    ss << "Busy: ";
    for (int i = 0; i < busy.size(); i++) {
        ss << (int)busy[i];
    }
    ss << "\n";
    return ss.str();
}

// Scoreboard functions

bool
RegisterFile::operandsReady(Wavefront *w, GPUDynInstPtr ii) const
{
    return true;
}

bool
RegisterFile::regBusy(int idx) const
{
    return busy.at(idx);
}

void
RegisterFile::markReg(int regIdx, bool value)
{
    DPRINTF(GPURF, "SIMD[%d] markReg(): physReg[%d] = %d\n",
            simdId, regIdx, (int)value);
    busy.at(regIdx) = value;
}

void
RegisterFile::enqRegFreeEvent(uint32_t regIdx, uint64_t delay)
{
    DPRINTF(GPURF, "SIMD[%d] enqRegFreeEvent physReg[%d] at %llu\n",
            simdId, regIdx, curTick() + delay);
    schedule(new MarkRegFreeScbEvent(this, regIdx),
             curTick() + delay);
}

void
RegisterFile::enqRegBusyEvent(uint32_t regIdx, uint64_t delay)
{
    DPRINTF(GPURF, "SIMD[%d] enqRegBusyEvent physReg[%d] at %llu\n",
            simdId, regIdx, curTick() + delay);
    schedule(new MarkRegBusyScbEvent(this, regIdx),
             curTick() + delay);
}

// Schedule functions
bool
RegisterFile::canScheduleReadOperands(Wavefront *w, GPUDynInstPtr ii)
{
    return true;
}

void
RegisterFile::scheduleReadOperands(Wavefront *w, GPUDynInstPtr ii)
{
}

bool
RegisterFile::canScheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii)
{
    return true;
}

void
RegisterFile::scheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii)
{
}

bool
RegisterFile::canScheduleWriteOperandsFromLoad(Wavefront *w, GPUDynInstPtr ii)
{
    return true;
}

void
RegisterFile::scheduleWriteOperandsFromLoad(Wavefront *w, GPUDynInstPtr ii)
{
}

bool
RegisterFile::operandReadComplete(Wavefront *w, GPUDynInstPtr ii)
{
    return true;
}

// Exec functions
void
RegisterFile::exec()
{
}

void
RegisterFile::waveExecuteInst(Wavefront *w, GPUDynInstPtr ii)
{
}

RegisterFile*
RegisterFileParams::create()
{
    return new RegisterFile(this);
}

// Events

// Mark a register as free in the scoreboard/busy vector
void
RegisterFile::MarkRegFreeScbEvent::process()
{
    rf->markReg(regIdx, false);
}

// Mark a register as busy in the scoreboard/busy vector
void
RegisterFile::MarkRegBusyScbEvent::process()
{
    rf->markReg(regIdx, true);
}

void
RegisterFile::dispatchInstruction(GPUDynInstPtr ii)
{
}

void
RegisterFile::regStats()
{
    registerReads
        .name(name() + ".register_reads")
        .desc("Total number of DWORDs read from register file")
        ;

    registerWrites
        .name(name() + ".register_writes")
        .desc("Total number of DWORDS written to register file")
        ;

    sramReads
        .name(name() + ".sram_reads")
        .desc("Total number of register file bank SRAM activations for reads")
        ;

    sramWrites
        .name(name() + ".sram_writes")
        .desc("Total number of register file bank SRAM activations for writes")
        ;
}
