/*
 * Copyright (c) 2007 MIPS Technologies, 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: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders 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
 * OWNER 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: Korey Sewell
 *
 */

#ifndef __CPU_INORDER_PIPELINE_STAGE_HH__
#define __CPU_INORDER_PIPELINE_STAGE_HH__

#include <queue>
#include <vector>

#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/inorder/inorder_dyn_inst.hh"
#include "cpu/inorder/comm.hh"
#include "params/InOrderCPU.hh"
#include "cpu/inorder/pipeline_traits.hh"

class InOrderCPU;

class PipelineStage
{
  protected:
    typedef ThePipeline::Params Params;
    typedef ThePipeline::DynInstPtr DynInstPtr;

  public:
    /** Overall stage status. Used to determine if the CPU can
     * deschedule itself due to a lack of activity.
     */
    enum StageStatus {
        Active,
        Inactive
    };

    /** Individual thread status. */
    enum ThreadStatus {
        Running,
        Idle,
        StartSquash,
        Squashing,
        Blocked,
        Unblocking,
        MemWaitResponse,
        MemWaitRetry,
        MemAccessComplete
    };

  protected:
    /** The Number of This Pipeline Stage */
    unsigned stageNum;

    /** The width of stage, in instructions. */
    unsigned stageWidth;

    /** Number of Threads*/
    ThreadID numThreads;

    /** Stage status. */
    StageStatus _status;

    /** Per-thread status. */
    ThreadStatus stageStatus[ThePipeline::MaxThreads];

  public:
    PipelineStage(Params *params, unsigned stage_num);

    /** MUST use init() function if this constructor is used. */
    PipelineStage() { }

    virtual ~PipelineStage() { }

    /** PipelineStage initialization. */
    void init(Params *params);

    /** Returns the name of stage. */
    std::string name() const;

    /** Registers statistics. */
    void regStats();

    /** Sets CPU pointer. */
    virtual void setCPU(InOrderCPU *cpu_ptr);

    virtual void scheduleStageStart(int delay, ThreadID tid) { }

    /** Sets the main backwards communication time buffer pointer. */
    void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);

    /** Sets pointer to time buffer coming from fetch. */
    void setPrevStageQueue(TimeBuffer<InterStageStruct> *prev_stage_ptr);

    /** Sets pointer to time buffer used to communicate to the next stage. */
    void setNextStageQueue(TimeBuffer<InterStageStruct> *next_stage_ptr);

    /** Sets pointer to list of active threads. */
    void setActiveThreads(std::list<ThreadID> *at_ptr);

    bool nextStageQueueValid(int stage_num);

    bool isBlocked(ThreadID tid);

    /** Changes the status of this stage to active, and indicates this
     * to the CPU.
     */
    //inline void switchToActive();

    /** Changes the status of this stage to inactive, and indicates
     * this to the CPU.
     */
    //inline void switchToInactive();

    /** Switches out the stage stage. */
    void switchOut();

    /** Takes over from another CPU's thread. */
    void takeOverFrom();

    /** Ticks stage, processing all input signals and executing as many
     *  instructions as possible.
     */
    virtual void tick();

    /** Set a resource stall in the pipeline-stage */
    void setResStall(ResReqPtr res_req, ThreadID tid);

    /** Unset a resource stall in the pipeline-stage */
    void unsetResStall(ResReqPtr res_req, ThreadID tid);

    /** Remove all stall signals for a particular thread; */
    virtual void removeStalls(ThreadID tid);

    /** Is there room in the stage buffer? */
    int stageBufferAvail();

  protected:
    /** Evaluate Stage Conditions and then process stage */
    virtual void processStage(bool &status_change);

    /** Determines what to do based on stage's current status.
     * @param status_change stage() sets this variable if there was a status
     * change (ie switching from from blocking to unblocking).
     * @param tid Thread id to stage instructions from.
     */
    virtual void processThread(bool &status_change, ThreadID tid);

    /** Processes instructions from fetch and passes them on to rename.
     * Decoding of instructions actually happens when they are created in
     * fetch, so this function mostly checks if PC-relative branches are
     * correct.
     */
    virtual void processInsts(ThreadID tid);

    /** Process all resources on an instruction's resource schedule */
    virtual bool processInstSchedule(DynInstPtr inst);

    /** Is there room in the next stage buffer for this instruction? */
    virtual bool canSendInstToStage(unsigned stage_num);

    /** Send an instruction to the next stage buffer */
    virtual bool sendInstToNextStage(DynInstPtr inst);

    /** Inserts a thread's instructions into the skid buffer, to be staged
     * once stage unblocks.
     */
    virtual void skidInsert(ThreadID tid);

    /** Total size of all skid buffers */
    int skidSize();

    /** Returns if all of the skid buffers are empty. */
    bool skidsEmpty();

    /** Updates overall stage status based on all of the threads' statuses. */
    virtual void updateStatus();

    /** Separates instructions from fetch into individual lists of instructions
     * sorted by thread.
     */
    void sortInsts();

    /** Reads all stall signals from the backwards communication timebuffer. */
    virtual void readStallSignals(ThreadID tid);

    /** Checks all input signals and updates stage's status appropriately. */
    virtual bool checkSignalsAndUpdate(ThreadID tid);

    /** Checks all stall signals, and returns if any are true. */
    virtual bool checkStall(ThreadID tid) const;

    /** Returns if there any instructions from the previous stage
     * on this cycle.
     */
    inline bool prevStageInstsValid();

    /** Switches stage to blocking, and signals back that stage has
     * become blocked.
     * @return Returns true if there is a status change.
     */
    virtual bool block(ThreadID tid);

    void blockDueToBuffer(ThreadID tid);

    /** Switches stage to unblocking if the skid buffer is empty, and
     * signals back that stage has unblocked.
     * @return Returns true if there is a status change.
     */
    virtual bool unblock(ThreadID tid);


  public:
    /** Squashes if there is a PC-relative branch that was predicted
     * incorrectly. Sends squash information back to fetch.
     */
    virtual void squashDueToBranch(DynInstPtr &inst, ThreadID tid);

    /** Squash instructions from stage buffer  */
    virtual void squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid);

    /** Squashes due to commit signalling a squash. Changes status to
     *  squashing and clears block/unblock signals as needed.
     */
    virtual void squash(InstSeqNum squash_num, ThreadID tid);

    void dumpInsts();

  protected:
    /** CPU interface. */
    InOrderCPU *cpu;

    Trace::InOrderTrace *tracer;

    /** List of active thread ids */
    std::list<ThreadID> *activeThreads;

    /** Queue of all instructions coming from previous stage on this cycle. */
    std::queue<DynInstPtr> insts[ThePipeline::MaxThreads];

    /** Queue of instructions that are finished processing and ready to go next stage.
     *  This is used to prevent from processing an instrution more than once on any
     *  stage. NOTE: It is up to the PROGRAMMER must manage this as a queue
     */
    std::list<DynInstPtr> instsToNextStage;

    /** Skid buffer between previous stage and this one. */
    std::queue<DynInstPtr> skidBuffer[ThePipeline::MaxThreads];

    /** Instruction used to signify that there is no *real* instruction in buffer slot */
    DynInstPtr dummyBufferInst;

    /** SeqNum of Squashing Branch Delay Instruction (used for MIPS) */
    Addr bdelayDoneSeqNum[ThePipeline::MaxThreads];

    /** Instruction used for squashing branch (used for MIPS) */
    DynInstPtr squashInst[ThePipeline::MaxThreads];

    /** Tells when their is a pending delay slot inst. to send
     *  to rename. If there is, then wait squash after the next
     *  instruction (used for MIPS).
     */
    bool squashAfterDelaySlot[ThePipeline::MaxThreads];

    /** Maximum size of the inter-stage buffer connecting the previous stage to
     *  this stage (which we call a skid buffer) */
    unsigned stageBufferMax;

    /** Variable that tracks if stage has written to the time buffer this
     * cycle. Used to tell CPU if there is activity this cycle.
     */
    bool wroteToTimeBuffer;

    /** Index of instructions being sent to the next stage. */
    unsigned toNextStageIndex;

    /** The last stage that this particular stage should look for stalls */
    int lastStallingStage[ThePipeline::MaxThreads];

    /** Time buffer interface. */
    TimeBuffer<TimeStruct> *timeBuffer;

  public:
    /** Wire to get rename's output from backwards time buffer. */
    TimeBuffer<TimeStruct>::wire fromNextStages;

    /** Wire to get iew's information from backwards time buffer. */
    TimeBuffer<TimeStruct>::wire toPrevStages;

    /** Instruction queue linking previous stage */
    TimeBuffer<InterStageStruct> *prevStageQueue;

    /** Wire to get the previous stage's. */
    TimeBuffer<InterStageStruct>::wire prevStage;

    /** Instruction queue linking next stage */
    TimeBuffer<InterStageStruct> *nextStageQueue;

    /** Wire to write to the next stage */
    TimeBuffer<InterStageStruct>::wire nextStage;

    /** Is Previous Stage Valid? */
    bool prevStageValid;

    /** Is Next Stage Valid? */
    bool nextStageValid;

    /** Source of possible stalls. */
    struct Stalls {
        bool stage[ThePipeline::NumStages];
        std::vector<ResReqPtr> resources;
    };

    /** Tracks which stages are telling decode to stall. */
    Stalls stalls[ThePipeline::MaxThreads];

    //@TODO: Use Stats for the pipeline stages
    /** Stat for total number of idle cycles. */
    //Stats::Scalar stageIdleCycles;
    /** Stat for total number of blocked cycles. */
    //Stats::Scalar stageBlockedCycles;
    /** Stat for total number of normal running cycles. */
    //Stats::Scalar stageRunCycles;
    /** Stat for total number of unblocking cycles. */
    //Stats::Scalar stageUnblockCycles;
    /** Stat for total number of squashing cycles. */
    //Stats::Scalar stageSquashCycles;
    /** Stat for total number of staged instructions. */
    //Stats::Scalar stageProcessedInsts;
    /** Stat for total number of squashed instructions. */
    //Stats::Scalar stageSquashedInsts;
};

#endif
