rob.hh revision 1461
17404SAli.Saidi@ARM.com// Todo: Probably add in support for scheduling events (more than one as
211580SDylan.Johnson@ARM.com// well) on the case of the ROB being empty or full.  Considering tracking
37404SAli.Saidi@ARM.com// free entries instead of insts in ROB.  Differentiate between squashing
47404SAli.Saidi@ARM.com// all instructions after the instruction, and all instructions after *and*
57404SAli.Saidi@ARM.com// including that instruction.
67404SAli.Saidi@ARM.com
77404SAli.Saidi@ARM.com#ifndef __CPU_BETA_CPU_ROB_HH__
87404SAli.Saidi@ARM.com#define __CPU_BETA_CPU_ROB_HH__
97404SAli.Saidi@ARM.com
107404SAli.Saidi@ARM.com#include <utility>
117404SAli.Saidi@ARM.com#include <vector>
127404SAli.Saidi@ARM.com
137404SAli.Saidi@ARM.com//#include "arch/alpha/isa_traits.hh"
147404SAli.Saidi@ARM.com
157404SAli.Saidi@ARM.com/**
167404SAli.Saidi@ARM.com * ROB class.  Uses the instruction list that exists within the CPU to
177404SAli.Saidi@ARM.com * represent the ROB.  This class doesn't contain that list, but instead
187404SAli.Saidi@ARM.com * a pointer to the CPU to get access to the list.  The ROB, in this first
197404SAli.Saidi@ARM.com * implementation, is largely what drives squashing.
207404SAli.Saidi@ARM.com */
217404SAli.Saidi@ARM.comtemplate <class Impl>
227404SAli.Saidi@ARM.comclass ROB
237404SAli.Saidi@ARM.com{
247404SAli.Saidi@ARM.com  public:
257404SAli.Saidi@ARM.com    //Typedefs from the Impl.
267404SAli.Saidi@ARM.com    typedef typename Impl::FullCPU FullCPU;
277404SAli.Saidi@ARM.com    typedef typename Impl::DynInstPtr DynInstPtr;
287404SAli.Saidi@ARM.com
297404SAli.Saidi@ARM.com    typedef std::pair<RegIndex, PhysRegIndex> UnmapInfo_t;
307404SAli.Saidi@ARM.com    typedef typename list<DynInstPtr>::iterator InstIt_t;
317404SAli.Saidi@ARM.com
327404SAli.Saidi@ARM.com  public:
337404SAli.Saidi@ARM.com    /** ROB constructor.
347404SAli.Saidi@ARM.com     *  @params _numEntries Number of entries in ROB.
357404SAli.Saidi@ARM.com     *  @params _squashWidth Number of instructions that can be squashed in a
367404SAli.Saidi@ARM.com     *                       single cycle.
377404SAli.Saidi@ARM.com     */
3810037SARM gem5 Developers    ROB(unsigned _numEntries, unsigned _squashWidth);
397404SAli.Saidi@ARM.com
407404SAli.Saidi@ARM.com    /** Function to set the CPU pointer, necessary due to which object the ROB
417404SAli.Saidi@ARM.com     *  is created within.
427404SAli.Saidi@ARM.com     *  @params cpu_ptr Pointer to the implementation specific full CPU object.
437404SAli.Saidi@ARM.com     */
447578Sdam.sunwoo@arm.com    void setCPU(FullCPU *cpu_ptr);
457578Sdam.sunwoo@arm.com
467404SAli.Saidi@ARM.com    /** Function to insert an instruction into the ROB.  The parameter inst is
4710037SARM gem5 Developers     *  not truly required, but is useful for checking correctness.  Note
487404SAli.Saidi@ARM.com     *  that whatever calls this function must ensure that there is enough
497404SAli.Saidi@ARM.com     *  space within the ROB for the new instruction.
507404SAli.Saidi@ARM.com     *  @params inst The instruction being inserted into the ROB.
5113892Sgabeblack@google.com     *  @todo Remove the parameter once correctness is ensured.
527404SAli.Saidi@ARM.com     */
537404SAli.Saidi@ARM.com    void insertInst(DynInstPtr &inst);
547404SAli.Saidi@ARM.com
557404SAli.Saidi@ARM.com    /** Returns pointer to the head instruction within the ROB.  There is
5610873Sandreas.sandberg@arm.com     *  no guarantee as to the return value if the ROB is empty.
5710873Sandreas.sandberg@arm.com     *  @retval Pointer to the DynInst that is at the head of the ROB.
587404SAli.Saidi@ARM.com     */
597404SAli.Saidi@ARM.com    DynInstPtr readHeadInst() { return cpu->instList.front(); }
607404SAli.Saidi@ARM.com
6110037SARM gem5 Developers    DynInstPtr readTailInst() { return (*tail); }
627404SAli.Saidi@ARM.com
6313892Sgabeblack@google.com    void retireHead();
647404SAli.Saidi@ARM.com
657694SAli.Saidi@ARM.com    bool isHeadReady();
6610037SARM gem5 Developers
6710037SARM gem5 Developers    unsigned numFreeEntries();
6810037SARM gem5 Developers
6910037SARM gem5 Developers    bool isFull()
7010037SARM gem5 Developers    { return numInstsInROB == numEntries; }
7110037SARM gem5 Developers
7210037SARM gem5 Developers    bool isEmpty()
7310037SARM gem5 Developers    { return numInstsInROB == 0; }
7410037SARM gem5 Developers
7510037SARM gem5 Developers    void doSquash();
7610037SARM gem5 Developers
7710037SARM gem5 Developers    void squash(InstSeqNum squash_num);
7810037SARM gem5 Developers
7910037SARM gem5 Developers    uint64_t readHeadPC();
8010037SARM gem5 Developers
8110037SARM gem5 Developers    uint64_t readHeadNextPC();
8210037SARM gem5 Developers
8310037SARM gem5 Developers    InstSeqNum readHeadSeqNum();
8410037SARM gem5 Developers
8510037SARM gem5 Developers    uint64_t readTailPC();
8610037SARM gem5 Developers
8710037SARM gem5 Developers    InstSeqNum readTailSeqNum();
8810037SARM gem5 Developers
8910037SARM gem5 Developers    /** Checks if the ROB is still in the process of squashing instructions.
9010037SARM gem5 Developers     *  @retval Whether or not the ROB is done squashing.
9110037SARM gem5 Developers     */
9210037SARM gem5 Developers    bool isDoneSquashing() const { return doneSquashing; }
9310037SARM gem5 Developers
947404SAli.Saidi@ARM.com    /** This is more of a debugging function than anything.  Use
957404SAli.Saidi@ARM.com     *  numInstsInROB to get the instructions in the ROB unless you are
967404SAli.Saidi@ARM.com     *  double checking that variable.
977404SAli.Saidi@ARM.com     */
987404SAli.Saidi@ARM.com    int countInsts();
997404SAli.Saidi@ARM.com
1007404SAli.Saidi@ARM.com  private:
1017404SAli.Saidi@ARM.com
1027436Sdam.sunwoo@arm.com    /** Pointer to the CPU. */
1037404SAli.Saidi@ARM.com    FullCPU *cpu;
1047404SAli.Saidi@ARM.com
1057436Sdam.sunwoo@arm.com    /** Number of instructions in the ROB. */
1067436Sdam.sunwoo@arm.com    unsigned numEntries;
1077436Sdam.sunwoo@arm.com
1087436Sdam.sunwoo@arm.com    /** Number of instructions that can be squashed in a single cycle. */
10910037SARM gem5 Developers    unsigned squashWidth;
11010537Sandreas.hansson@arm.com
11110037SARM gem5 Developers    /** Iterator pointing to the instruction which is the last instruction
11210037SARM gem5 Developers     *  in the ROB.  This may at times be invalid (ie when the ROB is empty),
11310037SARM gem5 Developers     *  however it should never be incorrect.
11410037SARM gem5 Developers     */
11510037SARM gem5 Developers    InstIt_t tail;
11610037SARM gem5 Developers
11710037SARM gem5 Developers    /** Iterator used for walking through the list of instructions when
11810037SARM gem5 Developers     *  squashing.  Used so that there is persistent state between cycles;
11910037SARM gem5 Developers     *  when squashing, the instructions are marked as squashed but not
12010037SARM gem5 Developers     *  immediately removed, meaning the tail iterator remains the same before
12110037SARM gem5 Developers     *  and after a squash.
12210037SARM gem5 Developers     *  This will always be set to cpu->instList.end() if it is invalid.
12310037SARM gem5 Developers     */
12410037SARM gem5 Developers    InstIt_t squashIt;
12510037SARM gem5 Developers
12610037SARM gem5 Developers    /** Number of instructions in the ROB. */
12710037SARM gem5 Developers    int numInstsInROB;
12810037SARM gem5 Developers
12910037SARM gem5 Developers    /** The sequence number of the squashed instruction. */
1307404SAli.Saidi@ARM.com    InstSeqNum squashedSeqNum;
1317404SAli.Saidi@ARM.com
1327404SAli.Saidi@ARM.com    /** Is the ROB done squashing. */
1337404SAli.Saidi@ARM.com    bool doneSquashing;
1347404SAli.Saidi@ARM.com};
1357404SAli.Saidi@ARM.com
1367404SAli.Saidi@ARM.com#endif //__CPU_BETA_CPU_ROB_HH__
1377404SAli.Saidi@ARM.com