/*
 * 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.
 */

#ifndef __REGISTER_FILE_HH__
#define __REGISTER_FILE_HH__

#include <limits>
#include <vector>

#include "base/statistics.hh"
#include "base/types.hh"
#include "gpu-compute/misc.hh"
#include "sim/sim_object.hh"

namespace gem5
{

class ComputeUnit;
class Shader;
class PoolManager;
class Wavefront;

struct RegisterFileParams;

// Abstract Register File
// This register file class can be inherited from to create both
// scalar and vector register files.
class RegisterFile : public SimObject
{
  public:
    RegisterFile(const RegisterFileParams &p);
    virtual ~RegisterFile();
    virtual void setParent(ComputeUnit *_computeUnit);
    int numRegs() const { return _numRegs; }

    // State functions

    // Scoreboard functions
    virtual bool operandsReady(Wavefront *w, GPUDynInstPtr ii) const;
    virtual bool regBusy(int idx) const;
    virtual void markReg(int regIdx, bool value);

    // Abstract Register Event
    class RegisterEvent : public Event
    {
      protected:
        RegisterFile *rf;
        int regIdx;

      public:
        RegisterEvent(RegisterFile *_rf, int _regIdx)
            : rf(_rf), regIdx(_regIdx) { setFlags(AutoDelete); }
    };

    // Register Event to mark a register as free in the scoreboard/busy vector
    class MarkRegFreeScbEvent : public RegisterEvent
    {
      public:
        MarkRegFreeScbEvent(RegisterFile *_rf, int _regIdx)
            : RegisterEvent(_rf, _regIdx) { }
        void process();
    };

    // Register Event to mark a register as busy in the scoreboard/busy vector
    class MarkRegBusyScbEvent : public RegisterEvent
    {
      public:
        MarkRegBusyScbEvent(RegisterFile *_rf, int _regIdx)
            : RegisterEvent(_rf, _regIdx) { }
        void process();
    };

    // Schedule an event to mark a register as free/busy in
    // the scoreboard/busy vector. Delay is already in Ticks
    virtual void enqRegFreeEvent(uint32_t regIdx, uint64_t delay);
    virtual void enqRegBusyEvent(uint32_t regIdx, uint64_t delay);

    // Schedule functions

    // The following functions are called by the SCH stage when attempting
    // to move a wave from the readyList to the schList.
    // canSchedule* checks if the RF is ready to provide operands for
    // the instruction, while schedule* requests the RF to begin reading
    // and writing of operands. Calling schedule* may only occur
    // immediately after canSchedule* was called and returned True
    virtual bool canScheduleReadOperands(Wavefront *w, GPUDynInstPtr ii);
    virtual bool canScheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii);
    virtual void scheduleReadOperands(Wavefront *w, GPUDynInstPtr ii);
    virtual void scheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii);

    // The following function is called to check if all operands
    // have been read for the given instruction
    virtual bool operandReadComplete(Wavefront *w, GPUDynInstPtr ii);

    // The following two functions are only called by returning loads to
    // check if the register file can support the incoming writes
    virtual bool canScheduleWriteOperandsFromLoad(Wavefront *w,
                                                  GPUDynInstPtr ii);
    // Queue the register writes. Assumes canScheduleWriteOperandsFromLoad
    // was called immediately prior and returned True
    virtual void scheduleWriteOperandsFromLoad(Wavefront *w,
                                               GPUDynInstPtr ii);

    // ExecRF is invoked every cycle by the compute unit and may be
    // used to model detailed timing of the register file.
    virtual void exec();

    // Called to inform RF that an instruction is executing
    // to schedule events for writeback, etc., as needed
    virtual void waveExecuteInst(Wavefront *w, GPUDynInstPtr ii);

    // Debug functions
    virtual std::string dump() const;

    virtual void dispatchInstruction(GPUDynInstPtr ii);

  protected:
    ComputeUnit* computeUnit;
    int simdId;

    // flag indicating if a register is busy
    std::vector<bool> busy;

    // numer of registers in this register file
    int _numRegs;

    struct RegisterFileStats : public statistics::Group
    {
        RegisterFileStats(statistics::Group *parent);

        // Total number of register reads per DWORD per thread
        statistics::Scalar registerReads;
        // Total number of register writes per DWORD per thread
        statistics::Scalar registerWrites;

        // Number of register file SRAM activations for reads.
        // The register file may be implemented with multiple SRAMs. This stat
        // tracks how many times the SRAMs are accessed for reads.
        statistics::Scalar sramReads;
        // Number of register file SRAM activations for writes
        statistics::Scalar sramWrites;
    } stats;
};

} // namespace gem5

#endif // __REGISTER_FILE_HH__
