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