rob.hh revision 1060
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 structure, but instead 20 * a pointer to the CPU to get access to the structure. The ROB has a large 21 * hand in squashing instructions within the CPU, and is responsible for 22 * sending out the squash signal as well as what instruction is to be 23 * squashed. The ROB also controls most of the calls to the CPU to delete 24 * instructions; the only other call is made in the first stage of the pipe- 25 * line, which tells the CPU to delete all instructions not in the ROB. 26 */ 27template<class Impl> 28class ROB 29{ 30 public: 31 //Typedefs from the Impl. 32 typedef typename Impl::FullCPU FullCPU; 33 typedef typename Impl::DynInst DynInst; 34 35 typedef pair<RegIndex, PhysRegIndex> UnmapInfo; 36 typedef typename list<DynInst *>::iterator InstIt; 37 38 public: 39 /** ROB constructor. 40 * @params _numEntries Number of entries in ROB. 41 * @params _squashWidth Number of instructions that can be squashed in a 42 * single cycle. 43 */ 44 ROB(unsigned _numEntries, unsigned _squashWidth); 45 46 /** Function to set the CPU pointer, necessary due to which object the ROB 47 * is created within. 48 * @params cpu_ptr Pointer to the implementation specific full CPU object. 49 */ 50 void setCPU(FullCPU *cpu_ptr); 51 52 /** Function to insert an instruction into the ROB. The parameter inst is 53 * not truly required, but is useful for checking correctness. Note 54 * that whatever calls this function must ensure that there is enough 55 * space within the ROB for the new instruction. 56 * @params inst The instruction being inserted into the ROB. 57 * @todo Remove the parameter once correctness is ensured. 58 */ 59 void insertInst(DynInst *inst); 60 61 /** Returns pointer to the head instruction within the ROB. There is 62 * no guarantee as to the return value if the ROB is empty. 63 * @retval Pointer to the DynInst that is at the head of the ROB. 64 */ 65 DynInst *readHeadInst() { return cpu->instList.front(); } 66 67 DynInst *readTailInst() { return (*tail); } 68 69 void retireHead(); 70 71 bool isHeadReady(); 72 73 unsigned numFreeEntries(); 74 75 bool isFull() 76 { return numInstsInROB == numEntries; } 77 78 bool isEmpty() 79 { return numInstsInROB == 0; } 80 81 void doSquash(); 82 83 void squash(InstSeqNum squash_num); 84 85 uint64_t readHeadPC(); 86 87 uint64_t readHeadNextPC(); 88 89 InstSeqNum readHeadSeqNum(); 90 91 uint64_t readTailPC(); 92 93 InstSeqNum readTailSeqNum(); 94 95 /** Checks if the ROB is still in the process of squashing instructions. 96 * @retval Whether or not the ROB is done squashing. 97 */ 98 bool isDoneSquashing() const { return doneSquashing; } 99 100 /** This is more of a debugging function than anything. Use 101 * numInstsInROB to get the instructions in the ROB unless you are 102 * double checking that variable. 103 */ 104 int countInsts(); 105 106 private: 107 108 /** Pointer to the CPU. */ 109 FullCPU *cpu; 110 111 unsigned numEntries; 112 113 /** Number of instructions that can be squashed in a single cycle. */ 114 unsigned squashWidth; 115 116 InstIt tail; 117 118 InstIt squashIt; 119 120 int numInstsInROB; 121 122 /** The sequence number of the squashed instruction. */ 123 InstSeqNum squashedSeqNum; 124 125 /** Is the ROB done squashing. */ 126 bool doneSquashing; 127}; 128 129#endif //__ROB_HH__ 130