rob.hh revision 1461
1// Todo: Probably add in support for scheduling events (more than one as
2// well) on the case of the ROB being empty or full.  Considering tracking
3// free entries instead of insts in ROB.  Differentiate between squashing
4// all instructions after the instruction, and all instructions after *and*
5// including that instruction.
6
7#ifndef __CPU_BETA_CPU_ROB_HH__
8#define __CPU_BETA_CPU_ROB_HH__
9
10#include <utility>
11#include <vector>
12
13//#include "arch/alpha/isa_traits.hh"
14
15/**
16 * ROB class.  Uses the instruction list that exists within the CPU to
17 * represent the ROB.  This class doesn't contain that list, but instead
18 * a pointer to the CPU to get access to the list.  The ROB, in this first
19 * implementation, is largely what drives squashing.
20 */
21template <class Impl>
22class ROB
23{
24  public:
25    //Typedefs from the Impl.
26    typedef typename Impl::FullCPU FullCPU;
27    typedef typename Impl::DynInstPtr DynInstPtr;
28
29    typedef std::pair<RegIndex, PhysRegIndex> UnmapInfo_t;
30    typedef typename list<DynInstPtr>::iterator InstIt_t;
31
32  public:
33    /** ROB constructor.
34     *  @params _numEntries Number of entries in ROB.
35     *  @params _squashWidth Number of instructions that can be squashed in a
36     *                       single cycle.
37     */
38    ROB(unsigned _numEntries, unsigned _squashWidth);
39
40    /** Function to set the CPU pointer, necessary due to which object the ROB
41     *  is created within.
42     *  @params cpu_ptr Pointer to the implementation specific full CPU object.
43     */
44    void setCPU(FullCPU *cpu_ptr);
45
46    /** Function to insert an instruction into the ROB.  The parameter inst is
47     *  not truly required, but is useful for checking correctness.  Note
48     *  that whatever calls this function must ensure that there is enough
49     *  space within the ROB for the new instruction.
50     *  @params inst The instruction being inserted into the ROB.
51     *  @todo Remove the parameter once correctness is ensured.
52     */
53    void insertInst(DynInstPtr &inst);
54
55    /** Returns pointer to the head instruction within the ROB.  There is
56     *  no guarantee as to the return value if the ROB is empty.
57     *  @retval Pointer to the DynInst that is at the head of the ROB.
58     */
59    DynInstPtr readHeadInst() { return cpu->instList.front(); }
60
61    DynInstPtr readTailInst() { return (*tail); }
62
63    void retireHead();
64
65    bool isHeadReady();
66
67    unsigned numFreeEntries();
68
69    bool isFull()
70    { return numInstsInROB == numEntries; }
71
72    bool isEmpty()
73    { return numInstsInROB == 0; }
74
75    void doSquash();
76
77    void squash(InstSeqNum squash_num);
78
79    uint64_t readHeadPC();
80
81    uint64_t readHeadNextPC();
82
83    InstSeqNum readHeadSeqNum();
84
85    uint64_t readTailPC();
86
87    InstSeqNum readTailSeqNum();
88
89    /** Checks if the ROB is still in the process of squashing instructions.
90     *  @retval Whether or not the ROB is done squashing.
91     */
92    bool isDoneSquashing() const { return doneSquashing; }
93
94    /** This is more of a debugging function than anything.  Use
95     *  numInstsInROB to get the instructions in the ROB unless you are
96     *  double checking that variable.
97     */
98    int countInsts();
99
100  private:
101
102    /** Pointer to the CPU. */
103    FullCPU *cpu;
104
105    /** Number of instructions in the ROB. */
106    unsigned numEntries;
107
108    /** Number of instructions that can be squashed in a single cycle. */
109    unsigned squashWidth;
110
111    /** Iterator pointing to the instruction which is the last instruction
112     *  in the ROB.  This may at times be invalid (ie when the ROB is empty),
113     *  however it should never be incorrect.
114     */
115    InstIt_t tail;
116
117    /** Iterator used for walking through the list of instructions when
118     *  squashing.  Used so that there is persistent state between cycles;
119     *  when squashing, the instructions are marked as squashed but not
120     *  immediately removed, meaning the tail iterator remains the same before
121     *  and after a squash.
122     *  This will always be set to cpu->instList.end() if it is invalid.
123     */
124    InstIt_t squashIt;
125
126    /** Number of instructions in the ROB. */
127    int numInstsInROB;
128
129    /** The sequence number of the squashed instruction. */
130    InstSeqNum squashedSeqNum;
131
132    /** Is the ROB done squashing. */
133    bool doneSquashing;
134};
135
136#endif //__CPU_BETA_CPU_ROB_HH__
137