rob.hh revision 2348
11689SN/A/* 22329SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292831Sksewell@umich.edu#ifndef __CPU_O3_ROB_HH__ 301689SN/A#define __CPU_O3_ROB_HH__ 311689SN/A 322292SN/A#include <string> 332292SN/A#include <utility> 341060SN/A#include <vector> 352292SN/A 361461SN/A/** 371461SN/A * ROB class. The ROB is largely what drives squashing. 381060SN/A */ 398230Snate@binkert.orgtemplate <class Impl> 408230Snate@binkert.orgclass ROB 416658Snate@binkert.org{ 426658Snate@binkert.org protected: 431060SN/A typedef TheISA::RegIndex RegIndex; 442292SN/A public: 451060SN/A //Typedefs from the Impl. 461061SN/A typedef typename Impl::FullCPU FullCPU; 471060SN/A typedef typename Impl::DynInstPtr DynInstPtr; 481060SN/A 492107SN/A typedef std::pair<RegIndex, PhysRegIndex> UnmapInfo; 502107SN/A typedef typename std::list<DynInstPtr>::iterator InstIt; 511060SN/A 521060SN/A /** Possible ROB statuses. */ 532733Sktlim@umich.edu enum Status { 541061SN/A Running, 551060SN/A Idle, 562292SN/A ROBSquashing 572292SN/A }; 582292SN/A 592292SN/A /** SMT ROB Sharing Policy */ 602292SN/A enum ROBPolicy{ 612292SN/A Dynamic, 622292SN/A Partitioned, 632329SN/A Threshold 642292SN/A }; 652292SN/A 662292SN/A private: 672292SN/A /** Per-thread ROB status. */ 682292SN/A Status robStatus[Impl::MaxThreads]; 692292SN/A 702292SN/A /** ROB resource sharing policy for SMT mode. */ 712292SN/A ROBPolicy robPolicy; 722292SN/A 732292SN/A public: 742292SN/A /** ROB constructor. 752292SN/A * @param _numEntries Number of entries in ROB. 762292SN/A * @param _squashWidth Number of instructions that can be squashed in a 772292SN/A * single cycle. 782292SN/A * @param _smtROBPolicy ROB Partitioning Scheme for SMT. 791060SN/A * @param _smtROBThreshold Max Resources(by %) a thread can have in the ROB. 801060SN/A * @param _numThreads The number of active threads. 811060SN/A */ 822292SN/A ROB(unsigned _numEntries, unsigned _squashWidth, std::string smtROBPolicy, 832292SN/A unsigned _smtROBThreshold, unsigned _numThreads); 842292SN/A 852292SN/A std::string name() const; 862292SN/A 872292SN/A /** Function to set the CPU pointer, necessary due to which object the ROB 881060SN/A * is created within. 894329Sktlim@umich.edu * @param cpu_ptr Pointer to the implementation specific full CPU object. 904329Sktlim@umich.edu */ 916221Snate@binkert.org void setCPU(FullCPU *cpu_ptr); 922292SN/A 932292SN/A /** Sets pointer to the list of active threads. 941060SN/A * @param at_ptr Pointer to the list of active threads. 952292SN/A */ 962292SN/A void setActiveThreads(std::list<unsigned>* at_ptr); 972292SN/A 986221Snate@binkert.org /** Switches out the ROB. */ 992292SN/A void switchOut(); 1002348SN/A 1012307SN/A /** Takes over another CPU's thread. */ 1022307SN/A void takeOverFrom(); 1032348SN/A 1042307SN/A /** Function to insert an instruction into the ROB. Note that whatever 1052307SN/A * calls this function must ensure that there is enough space within the 1062292SN/A * ROB for the new instruction. 1072292SN/A * @param inst The instruction being inserted into the ROB. 1082292SN/A */ 1091763SN/A void insertInst(DynInstPtr &inst); 1101060SN/A 1111061SN/A /** Returns pointer to the head instruction within the ROB. There is 1121060SN/A * no guarantee as to the return value if the ROB is empty. 1131060SN/A * @retval Pointer to the DynInst that is at the head of the ROB. 1141060SN/A */ 1151060SN/A// DynInstPtr readHeadInst(); 1161060SN/A 1172329SN/A /** Returns a pointer to the head instruction of a specific thread within 1181060SN/A * the ROB. 1192292SN/A * @return Pointer to the DynInst that is at the head of the ROB. 1202292SN/A */ 1212292SN/A DynInstPtr readHeadInst(unsigned tid); 1222292SN/A 1236221Snate@binkert.org /** Returns pointer to the tail instruction within the ROB. There is 1241060SN/A * no guarantee as to the return value if the ROB is empty. 1252292SN/A * @retval Pointer to the DynInst that is at the tail of the ROB. 1262292SN/A */ 1272292SN/A// DynInstPtr readTailInst(); 1282292SN/A 1292329SN/A /** Returns a pointer to the tail instruction of a specific thread within 1301060SN/A * the ROB. 1312292SN/A * @return Pointer to the DynInst that is at the tail of the ROB. 1322292SN/A */ 1332292SN/A DynInstPtr readTailInst(unsigned tid); 1342292SN/A 1356221Snate@binkert.org /** Retires the head instruction, removing it from the ROB. */ 1361060SN/A// void retireHead(); 1372292SN/A 1382329SN/A /** Retires the head instruction of a specific thread, removing it from the 1392107SN/A * ROB. 1402292SN/A */ 1412292SN/A void retireHead(unsigned tid); 1422292SN/A 1436221Snate@binkert.org /** Is the oldest instruction across all threads ready. */ 1442292SN/A// bool isHeadReady(); 1452292SN/A 1462329SN/A /** Is the oldest instruction across a particular thread ready. */ 1472107SN/A bool isHeadReady(unsigned tid); 1482292SN/A 1496221Snate@binkert.org /** Is there any commitable head instruction across all threads ready. */ 1502292SN/A bool canCommit(); 1512292SN/A 1522292SN/A /** Re-adjust ROB partitioning. */ 1532292SN/A void resetEntries(); 1542292SN/A 1552292SN/A /** Number of entries needed For 'num_threads' amount of threads. */ 1562292SN/A int entryAmount(int num_threads); 1572292SN/A 1586221Snate@binkert.org /** Returns the number of total free entries in the ROB. */ 1592292SN/A unsigned numFreeEntries(); 1602292SN/A 1611060SN/A /** Returns the number of free entries in a specific ROB paritition. */ 1621060SN/A unsigned numFreeEntries(unsigned tid); 1632292SN/A 1646221Snate@binkert.org /** Returns the maximum number of entries for a specific thread. */ 1652292SN/A unsigned getMaxEntries(unsigned tid) 1662292SN/A { return maxEntries[tid]; } 1676221Snate@binkert.org 1682292SN/A /** Returns the number of entries being used by a specific thread. */ 1692292SN/A unsigned getThreadEntries(unsigned tid) 1702292SN/A { return threadEntries[tid]; } 1716221Snate@binkert.org 1722292SN/A /** Returns if the ROB is full. */ 1732292SN/A bool isFull() 1742292SN/A { return numInstsInROB == numEntries; } 1751060SN/A 1761060SN/A /** Returns if a specific thread's partition is full. */ 1771060SN/A bool isFull(unsigned tid) 1782292SN/A { return threadEntries[tid] == numEntries; } 1796221Snate@binkert.org 1802292SN/A /** Returns if the ROB is empty. */ 1812292SN/A bool isEmpty() 1822292SN/A { return numInstsInROB == 0; } 1831060SN/A 1841060SN/A /** Returns if a specific thread's partition is empty. */ 1851060SN/A bool isEmpty(unsigned tid) 1862292SN/A { return threadEntries[tid] == 0; } 1876221Snate@binkert.org 1882292SN/A /** Executes the squash, marking squashed instructions. */ 1891060SN/A void doSquash(unsigned tid); 1902292SN/A 1916221Snate@binkert.org /** Squashes all instructions younger than the given sequence number for 1921060SN/A * the specific thread. 1932292SN/A */ 1942292SN/A void squash(InstSeqNum squash_num, unsigned tid); 1952292SN/A 1966221Snate@binkert.org /** Updates the head instruction with the new oldest instruction. */ 1971060SN/A void updateHead(); 1982292SN/A 1992292SN/A /** Updates the tail instruction with the new youngest instruction. */ 2001060SN/A void updateTail(); 2012292SN/A 2022292SN/A /** Reads the PC of the oldest head instruction. */ 2031060SN/A// uint64_t readHeadPC(); 2042292SN/A 2052329SN/A /** Reads the PC of the head instruction of a specific thread. */ 2061060SN/A// uint64_t readHeadPC(unsigned tid); 2072292SN/A 2086221Snate@binkert.org /** Reads the next PC of the oldest head instruction. */ 2092292SN/A// uint64_t readHeadNextPC(); 2102292SN/A 2112329SN/A /** Reads the next PC of the head instruction of a specific thread. */ 2122107SN/A// uint64_t readHeadNextPC(unsigned tid); 2132292SN/A 2146221Snate@binkert.org /** Reads the sequence number of the oldest head instruction. */ 2152292SN/A// InstSeqNum readHeadSeqNum(); 2162292SN/A 2172329SN/A /** Reads the sequence number of the head instruction of a specific thread. 2182107SN/A */ 2192292SN/A// InstSeqNum readHeadSeqNum(unsigned tid); 2202292SN/A 2216221Snate@binkert.org /** Reads the PC of the youngest tail instruction. */ 2222292SN/A// uint64_t readTailPC(); 2232292SN/A 2242329SN/A /** Reads the PC of the tail instruction of a specific thread. */ 2252107SN/A// uint64_t readTailPC(unsigned tid); 2262292SN/A 2276221Snate@binkert.org /** Reads the sequence number of the youngest tail instruction. */ 2282292SN/A// InstSeqNum readTailSeqNum(); 2292292SN/A 2302329SN/A /** Reads the sequence number of tail instruction of a specific thread. */ 2312107SN/A// InstSeqNum readTailSeqNum(unsigned tid); 2322292SN/A 2336221Snate@binkert.org /** Checks if the ROB is still in the process of squashing instructions. 2341060SN/A * @retval Whether or not the ROB is done squashing. 2351060SN/A */ 2361060SN/A bool isDoneSquashing(unsigned tid) const 2371060SN/A { return doneSquashing[tid]; } 2386221Snate@binkert.org 2392292SN/A /** Checks if the ROB is still in the process of squashing instructions for 2402292SN/A * any thread. 2412292SN/A */ 2422292SN/A bool isDoneSquashing(); 2432292SN/A 2442292SN/A /** This is more of a debugging function than anything. Use 2451060SN/A * numInstsInROB to get the instructions in the ROB unless you are 2461060SN/A * double checking that variable. 2471060SN/A */ 2481060SN/A int countInsts(); 2491060SN/A 2501060SN/A /** This is more of a debugging function than anything. Use 2511060SN/A * threadEntries to get the instructions in the ROB unless you are 2522292SN/A * double checking that variable. 2532292SN/A */ 2542292SN/A int countInsts(unsigned tid); 2552292SN/A 2566221Snate@binkert.org private: 2572292SN/A /** Pointer to the CPU. */ 2587897Shestness@cs.utexas.edu FullCPU *cpu; 2597897Shestness@cs.utexas.edu 2607897Shestness@cs.utexas.edu /** Active Threads in CPU */ 2611060SN/A std::list<unsigned>* activeThreads; 2621060SN/A 2632733Sktlim@umich.edu /** Number of instructions in the ROB. */ 2641060SN/A unsigned numEntries; 2652292SN/A 2666221Snate@binkert.org /** Entries Per Thread */ 2672292SN/A unsigned threadEntries[Impl::MaxThreads]; 2681061SN/A 2691060SN/A /** Max Insts a Thread Can Have in the ROB */ 2701060SN/A unsigned maxEntries[Impl::MaxThreads]; 2712292SN/A 2722292SN/A /** ROB List of Instructions */ 2732292SN/A std::list<DynInstPtr> instList[Impl::MaxThreads]; 2742292SN/A 2752292SN/A /** Number of instructions that can be squashed in a single cycle. */ 2762292SN/A unsigned squashWidth; 2772292SN/A 2782292SN/A public: 2792292SN/A /** Iterator pointing to the instruction which is the last instruction 2801060SN/A * in the ROB. This may at times be invalid (ie when the ROB is empty), 2811060SN/A * however it should never be incorrect. 2821060SN/A */ 2832292SN/A InstIt tail; 2841061SN/A 2851061SN/A /** Iterator pointing to the instruction which is the first instruction in 2861061SN/A * in the ROB*/ 2871061SN/A InstIt head; 2882292SN/A 2891060SN/A private: 2902292SN/A /** Iterator used for walking through the list of instructions when 2912292SN/A * squashing. Used so that there is persistent state between cycles; 2922292SN/A * when squashing, the instructions are marked as squashed but not 2932292SN/A * immediately removed, meaning the tail iterator remains the same before 2942292SN/A * and after a squash. 2951061SN/A * This will always be set to cpu->instList.end() if it is invalid. 2961061SN/A */ 2971061SN/A InstIt squashIt[Impl::MaxThreads]; 2981061SN/A 2991061SN/A public: 3001061SN/A /** Number of instructions in the ROB. */ 3011061SN/A int numInstsInROB; 3022292SN/A 3031060SN/A /** Dummy instruction returned if there are no insts left. */ 3042292SN/A DynInstPtr dummyInst; 3051061SN/A 3061060SN/A private: 3071060SN/A /** The sequence number of the squashed instruction. */ 3082348SN/A InstSeqNum squashedSeqNum; 3092292SN/A 3102292SN/A /** Is the ROB done squashing. */ 3112292SN/A bool doneSquashing[Impl::MaxThreads]; 3121060SN/A 3132877Sksewell@umich.edu /** Number of active threads. */ 3141060SN/A unsigned numThreads; 3151060SN/A}; 3162292SN/A 3172292SN/A#endif //__CPU_O3_ROB_HH__ 3182292SN/A