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