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

#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"

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; }
    virtual void regStats() override;

    // 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;
    // Stats
    // Total number of register reads, incremented once per DWORD per thread
    Stats::Scalar registerReads;
    // Total number of register writes, incremented once per DWORD per thread
    Stats::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.
    Stats::Scalar sramReads;
    // Number of register file SRAM activations for writes
    Stats::Scalar sramWrites;
};

#endif // __REGISTER_FILE_HH__
