inst_queue.hh revision 1684
16242Sgblack@eecs.umich.edu#ifndef __CPU_BETA_CPU_INST_QUEUE_HH__ 27093Sgblack@eecs.umich.edu#define __CPU_BETA_CPU_INST_QUEUE_HH__ 37093Sgblack@eecs.umich.edu 47093Sgblack@eecs.umich.edu#include <list> 57093Sgblack@eecs.umich.edu#include <map> 67093Sgblack@eecs.umich.edu#include <queue> 77093Sgblack@eecs.umich.edu#include <stdint.h> 87093Sgblack@eecs.umich.edu#include <vector> 97093Sgblack@eecs.umich.edu 107093Sgblack@eecs.umich.edu#include "base/statistics.hh" 117093Sgblack@eecs.umich.edu#include "base/timebuf.hh" 127093Sgblack@eecs.umich.edu#include "cpu/inst_seq.hh" 137093Sgblack@eecs.umich.edu 146242Sgblack@eecs.umich.edu/** 156242Sgblack@eecs.umich.edu * A standard instruction queue class. It holds instructions in an 166242Sgblack@eecs.umich.edu * array, holds the ordering of the instructions within a linked list, 176242Sgblack@eecs.umich.edu * and tracks producer/consumer dependencies within a separate linked 186242Sgblack@eecs.umich.edu * list. Similar to the rename map and the free list, it expects that 196242Sgblack@eecs.umich.edu * floating point registers have their indices start after the integer 206242Sgblack@eecs.umich.edu * registers (ie with 96 int and 96 fp registers, regs 0-95 are integer 216242Sgblack@eecs.umich.edu * and 96-191 are fp). This remains true even for both logical and 226242Sgblack@eecs.umich.edu * physical register indices. 236242Sgblack@eecs.umich.edu */ 246242Sgblack@eecs.umich.edutemplate <class Impl> 256242Sgblack@eecs.umich.educlass InstructionQueue 266242Sgblack@eecs.umich.edu{ 276242Sgblack@eecs.umich.edu public: 286242Sgblack@eecs.umich.edu //Typedefs from the Impl. 296242Sgblack@eecs.umich.edu typedef typename Impl::FullCPU FullCPU; 306242Sgblack@eecs.umich.edu typedef typename Impl::DynInstPtr DynInstPtr; 316242Sgblack@eecs.umich.edu typedef typename Impl::Params Params; 326242Sgblack@eecs.umich.edu 336242Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::MemDepUnit MemDepUnit; 346242Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::IssueStruct IssueStruct; 356242Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::TimeStruct TimeStruct; 366242Sgblack@eecs.umich.edu 376242Sgblack@eecs.umich.edu // Typedef of iterator through the list of instructions. Might be 386242Sgblack@eecs.umich.edu // better to untie this from the FullCPU or pass its information to 396242Sgblack@eecs.umich.edu // the stages. 406242Sgblack@eecs.umich.edu typedef typename std::list<DynInstPtr>::iterator ListIt; 416242Sgblack@eecs.umich.edu 426242Sgblack@eecs.umich.edu /** 436242Sgblack@eecs.umich.edu * Struct for comparing entries to be added to the priority queue. This 446242Sgblack@eecs.umich.edu * gives reverse ordering to the instructions in terms of sequence 456242Sgblack@eecs.umich.edu * numbers: the instructions with smaller sequence numbers (and hence 466242Sgblack@eecs.umich.edu * are older) will be at the top of the priority queue. 476242Sgblack@eecs.umich.edu */ 486242Sgblack@eecs.umich.edu struct pqCompare 496242Sgblack@eecs.umich.edu { 506242Sgblack@eecs.umich.edu bool operator() (const DynInstPtr &lhs, const DynInstPtr &rhs) const 516242Sgblack@eecs.umich.edu { 526242Sgblack@eecs.umich.edu return lhs->seqNum > rhs->seqNum; 536242Sgblack@eecs.umich.edu } 546242Sgblack@eecs.umich.edu }; 556242Sgblack@eecs.umich.edu 566242Sgblack@eecs.umich.edu /** 576242Sgblack@eecs.umich.edu * Struct for comparing entries to be added to the set. This gives 586242Sgblack@eecs.umich.edu * standard ordering in terms of sequence numbers. 596242Sgblack@eecs.umich.edu */ 606242Sgblack@eecs.umich.edu struct setCompare 616242Sgblack@eecs.umich.edu { 626242Sgblack@eecs.umich.edu bool operator() (const DynInstPtr &lhs, const DynInstPtr &rhs) const 636242Sgblack@eecs.umich.edu { 646242Sgblack@eecs.umich.edu return lhs->seqNum < rhs->seqNum; 657111Sgblack@eecs.umich.edu } 666242Sgblack@eecs.umich.edu }; 676242Sgblack@eecs.umich.edu 686242Sgblack@eecs.umich.edu typedef std::priority_queue<DynInstPtr, vector<DynInstPtr>, pqCompare> 696242Sgblack@eecs.umich.edu ReadyInstQueue; 707408Sgblack@eecs.umich.edu 716735Sgblack@eecs.umich.edu InstructionQueue(Params ¶ms); 726242Sgblack@eecs.umich.edu 736242Sgblack@eecs.umich.edu void regStats(); 746242Sgblack@eecs.umich.edu 756723Sgblack@eecs.umich.edu void setCPU(FullCPU *cpu); 766242Sgblack@eecs.umich.edu 776242Sgblack@eecs.umich.edu void setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2eQueue); 786261Sgblack@eecs.umich.edu 796403Sgblack@eecs.umich.edu void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 806403Sgblack@eecs.umich.edu 816403Sgblack@eecs.umich.edu unsigned numFreeEntries(); 827325Sgblack@eecs.umich.edu 837325Sgblack@eecs.umich.edu bool isFull(); 847400SAli.Saidi@ARM.com 857350SAli.Saidi@ARM.com void insert(DynInstPtr &new_inst); 867259Sgblack@eecs.umich.edu 877259Sgblack@eecs.umich.edu void insertNonSpec(DynInstPtr &new_inst); 887259Sgblack@eecs.umich.edu 897259Sgblack@eecs.umich.edu void advanceTail(DynInstPtr &inst); 907264Sgblack@eecs.umich.edu 917267Sgblack@eecs.umich.edu void scheduleReadyInsts(); 927285Sgblack@eecs.umich.edu 937265Sgblack@eecs.umich.edu void scheduleNonSpec(const InstSeqNum &inst); 947266Sgblack@eecs.umich.edu 957266Sgblack@eecs.umich.edu void wakeDependents(DynInstPtr &completed_inst); 967266Sgblack@eecs.umich.edu 977268Sgblack@eecs.umich.edu void violation(DynInstPtr &store, DynInstPtr &faulting_load); 987272Sgblack@eecs.umich.edu 997272Sgblack@eecs.umich.edu // Change this to take in the sequence number 1007271Sgblack@eecs.umich.edu void squash(); 1017273Sgblack@eecs.umich.edu 1027287Sgblack@eecs.umich.edu void doSquash(); 1037287Sgblack@eecs.umich.edu 1047274Sgblack@eecs.umich.edu void stopSquash(); 1057275Sgblack@eecs.umich.edu 1067276Sgblack@eecs.umich.edu private: 1077286Sgblack@eecs.umich.edu /** Pointer to the CPU. */ 1087297Sgblack@eecs.umich.edu FullCPU *cpu; 1097297Sgblack@eecs.umich.edu 1107298Sgblack@eecs.umich.edu /** The memory dependence unit, which tracks/predicts memory dependences 1117352Sgblack@eecs.umich.edu * between instructions. 1127352Sgblack@eecs.umich.edu */ 1137354Sgblack@eecs.umich.edu MemDepUnit memDepUnit; 1147353Sgblack@eecs.umich.edu 1157355Sgblack@eecs.umich.edu /** The queue to the execute stage. Issued instructions will be written 1167355Sgblack@eecs.umich.edu * into it. 1177355Sgblack@eecs.umich.edu */ 1187355Sgblack@eecs.umich.edu TimeBuffer<IssueStruct> *issueToExecuteQueue; 1197355Sgblack@eecs.umich.edu 1207355Sgblack@eecs.umich.edu /** The backwards time buffer. */ 1217355Sgblack@eecs.umich.edu TimeBuffer<TimeStruct> *timeBuffer; 1227355Sgblack@eecs.umich.edu 1237355Sgblack@eecs.umich.edu /** Wire to read information from timebuffer. */ 1247355Sgblack@eecs.umich.edu typename TimeBuffer<TimeStruct>::wire fromCommit; 1257355Sgblack@eecs.umich.edu 1267355Sgblack@eecs.umich.edu enum InstList { 1277355Sgblack@eecs.umich.edu Int, 1287355Sgblack@eecs.umich.edu Float, 1297362Sgblack@eecs.umich.edu Branch, 1307362Sgblack@eecs.umich.edu Memory, 1317362Sgblack@eecs.umich.edu Misc, 1327362Sgblack@eecs.umich.edu Squashed, 1337390Sgblack@eecs.umich.edu None 1347404SAli.Saidi@ARM.com }; 1357404SAli.Saidi@ARM.com 1367404SAli.Saidi@ARM.com /** List of ready int instructions. Used to keep track of the order in 1377404SAli.Saidi@ARM.com * which instructions should issue. 1387406SAli.Saidi@ARM.com */ 1397406SAli.Saidi@ARM.com ReadyInstQueue readyIntInsts; 1407406SAli.Saidi@ARM.com 1417436Sdam.sunwoo@arm.com /** List of ready floating point instructions. */ 1427436Sdam.sunwoo@arm.com ReadyInstQueue readyFloatInsts; 1437436Sdam.sunwoo@arm.com 1447436Sdam.sunwoo@arm.com /** List of ready branch instructions. */ 1457436Sdam.sunwoo@arm.com ReadyInstQueue readyBranchInsts; 1467436Sdam.sunwoo@arm.com 1477436Sdam.sunwoo@arm.com /** List of ready miscellaneous instructions. */ 1487436Sdam.sunwoo@arm.com ReadyInstQueue readyMiscInsts; 1497436Sdam.sunwoo@arm.com 1507583SAli.Saidi@arm.com /** List of squashed instructions (which are still valid and in IQ). 1517583SAli.Saidi@arm.com * Implemented using a priority queue; the entries must contain both 1527583SAli.Saidi@arm.com * the IQ index and sequence number of each instruction so that 1537583SAli.Saidi@arm.com * ordering based on sequence numbers can be used. 1547583SAli.Saidi@arm.com */ 1557583SAli.Saidi@arm.com ReadyInstQueue squashedInsts; 1567583SAli.Saidi@arm.com 1577583SAli.Saidi@arm.com /** List of non-speculative instructions that will be scheduled 1587583SAli.Saidi@arm.com * once the IQ gets a signal from commit. While it's redundant to 1597583SAli.Saidi@arm.com * have the key be a part of the value (the sequence number is stored 1607583SAli.Saidi@arm.com * inside of DynInst), when these instructions are woken up only 1617583SAli.Saidi@arm.com * the sequence number will be available. Thus it is most efficient to be 1627583SAli.Saidi@arm.com * able to search by the sequence number alone. 1637583SAli.Saidi@arm.com */ 1647583SAli.Saidi@arm.com std::map<InstSeqNum, DynInstPtr> nonSpecInsts; 1657583SAli.Saidi@arm.com 1667259Sgblack@eecs.umich.edu typedef typename std::map<InstSeqNum, DynInstPtr>::iterator non_spec_it_t; 1677406SAli.Saidi@ARM.com 1687259Sgblack@eecs.umich.edu /** Number of free IQ entries left. */ 1697259Sgblack@eecs.umich.edu unsigned freeEntries; 1707259Sgblack@eecs.umich.edu 1717259Sgblack@eecs.umich.edu /** The number of entries in the instruction queue. */ 1727259Sgblack@eecs.umich.edu unsigned numEntries; 1737259Sgblack@eecs.umich.edu 1747259Sgblack@eecs.umich.edu /** The number of integer instructions that can be issued in one 1757259Sgblack@eecs.umich.edu * cycle. 1767259Sgblack@eecs.umich.edu */ 1777259Sgblack@eecs.umich.edu unsigned intWidth; 1787259Sgblack@eecs.umich.edu 1797259Sgblack@eecs.umich.edu /** The number of floating point instructions that can be issued 1807259Sgblack@eecs.umich.edu * in one cycle. 1817259Sgblack@eecs.umich.edu */ 1827259Sgblack@eecs.umich.edu unsigned floatWidth; 1837259Sgblack@eecs.umich.edu 1847259Sgblack@eecs.umich.edu /** The number of branches that can be issued in one cycle. */ 1857259Sgblack@eecs.umich.edu unsigned branchWidth; 1867259Sgblack@eecs.umich.edu 1877351Sgblack@eecs.umich.edu /** The number of memory instructions that can be issued in one cycle. */ 1887351Sgblack@eecs.umich.edu unsigned memoryWidth; 1897351Sgblack@eecs.umich.edu 1907351Sgblack@eecs.umich.edu /** The total number of instructions that can be issued in one cycle. */ 1917351Sgblack@eecs.umich.edu unsigned totalWidth; 1927351Sgblack@eecs.umich.edu 1937259Sgblack@eecs.umich.edu //The number of physical registers in the CPU. 1947259Sgblack@eecs.umich.edu unsigned numPhysRegs; 1957259Sgblack@eecs.umich.edu 1967259Sgblack@eecs.umich.edu /** The number of physical integer registers in the CPU. */ 1977259Sgblack@eecs.umich.edu unsigned numPhysIntRegs; 1987259Sgblack@eecs.umich.edu 1997259Sgblack@eecs.umich.edu /** The number of floating point registers in the CPU. */ 2006735Sgblack@eecs.umich.edu unsigned numPhysFloatRegs; 2016261Sgblack@eecs.umich.edu 2026261Sgblack@eecs.umich.edu /** Delay between commit stage and the IQ. 2037259Sgblack@eecs.umich.edu * @todo: Make there be a distinction between the delays within IEW. 2047259Sgblack@eecs.umich.edu */ 2057259Sgblack@eecs.umich.edu unsigned commitToIEWDelay; 2066261Sgblack@eecs.umich.edu 2077408Sgblack@eecs.umich.edu ////////////////////////////////// 2087259Sgblack@eecs.umich.edu // Variables needed for squashing 2097351Sgblack@eecs.umich.edu ////////////////////////////////// 2107400SAli.Saidi@ARM.com 2117285Sgblack@eecs.umich.edu /** The sequence number of the squashed instruction. */ 2127267Sgblack@eecs.umich.edu InstSeqNum squashedSeqNum; 2137287Sgblack@eecs.umich.edu 2147287Sgblack@eecs.umich.edu /** Iterator that points to the youngest instruction in the IQ. */ 2157297Sgblack@eecs.umich.edu ListIt tail; 2167297Sgblack@eecs.umich.edu 2177355Sgblack@eecs.umich.edu /** Iterator that points to the last instruction that has been squashed. 2187355Sgblack@eecs.umich.edu * This will not be valid unless the IQ is in the process of squashing. 2197355Sgblack@eecs.umich.edu */ 2207355Sgblack@eecs.umich.edu ListIt squashIt; 2217355Sgblack@eecs.umich.edu 2227390Sgblack@eecs.umich.edu /////////////////////////////////// 2237436Sdam.sunwoo@arm.com // Dependency graph stuff 2247436Sdam.sunwoo@arm.com /////////////////////////////////// 2257436Sdam.sunwoo@arm.com 2267436Sdam.sunwoo@arm.com class DependencyEntry 2277583SAli.Saidi@arm.com { 2287583SAli.Saidi@arm.com public: 2297583SAli.Saidi@arm.com DynInstPtr inst; 2307583SAli.Saidi@arm.com //Might want to include data about what arch. register the 2317583SAli.Saidi@arm.com //dependence is waiting on. 2327583SAli.Saidi@arm.com DependencyEntry *next; 2337406SAli.Saidi@ARM.com 2347404SAli.Saidi@ARM.com //This function, and perhaps this whole class, stand out a little 2357583SAli.Saidi@arm.com //bit as they don't fit a classification well. I want access 2367259Sgblack@eecs.umich.edu //to the underlying structure of the linked list, yet at 2377583SAli.Saidi@arm.com //the same time it feels like this should be something abstracted 2387362Sgblack@eecs.umich.edu //away. So for now it will sit here, within the IQ, until 2397297Sgblack@eecs.umich.edu //a better implementation is decided upon. 2407272Sgblack@eecs.umich.edu // This function probably shouldn't be within the entry... 2417406SAli.Saidi@ARM.com void insert(DynInstPtr &new_inst); 2427404SAli.Saidi@ARM.com 2437259Sgblack@eecs.umich.edu void remove(DynInstPtr &inst_to_remove); 2446242Sgblack@eecs.umich.edu 2456242Sgblack@eecs.umich.edu // Debug variable, remove when done testing. 2466242Sgblack@eecs.umich.edu static unsigned mem_alloc_counter; 2476242Sgblack@eecs.umich.edu }; 2486242Sgblack@eecs.umich.edu 2496242Sgblack@eecs.umich.edu /** Array of linked lists. Each linked list is a list of all the 2506242Sgblack@eecs.umich.edu * instructions that depend upon a given register. The actual 2516242Sgblack@eecs.umich.edu * register's index is used to index into the graph; ie all 2526735Sgblack@eecs.umich.edu * instructions in flight that are dependent upon r34 will be 2536242Sgblack@eecs.umich.edu * in the linked list of dependGraph[34]. 2546242Sgblack@eecs.umich.edu */ 2556735Sgblack@eecs.umich.edu DependencyEntry *dependGraph; 2566242Sgblack@eecs.umich.edu 2576242Sgblack@eecs.umich.edu /** A cache of the recently woken registers. It is 1 if the register 2586242Sgblack@eecs.umich.edu * has been woken up recently, and 0 if the register has been added 2596242Sgblack@eecs.umich.edu * to the dependency graph and has not yet received its value. It 2606242Sgblack@eecs.umich.edu * is basically a secondary scoreboard, and should pretty much mirror 2616242Sgblack@eecs.umich.edu * the scoreboard that exists in the rename map. 2626242Sgblack@eecs.umich.edu */ 2636735Sgblack@eecs.umich.edu vector<bool> regScoreboard; 2647408Sgblack@eecs.umich.edu 2657408Sgblack@eecs.umich.edu bool addToDependents(DynInstPtr &new_inst); 2667408Sgblack@eecs.umich.edu void insertDependency(DynInstPtr &new_inst); 2677408Sgblack@eecs.umich.edu void createDependency(DynInstPtr &new_inst); 2687408Sgblack@eecs.umich.edu 2697408Sgblack@eecs.umich.edu void addIfReady(DynInstPtr &inst); 2707408Sgblack@eecs.umich.edu 2717408Sgblack@eecs.umich.edu private: 2726750Sgblack@eecs.umich.edu /** Debugging function to count how many entries are in the IQ. It does 2736750Sgblack@eecs.umich.edu * a linear walk through the instructions, so do not call this function 2746750Sgblack@eecs.umich.edu * during normal execution. 2756750Sgblack@eecs.umich.edu */ 2766735Sgblack@eecs.umich.edu int countInsts(); 2777360Sgblack@eecs.umich.edu 2786735Sgblack@eecs.umich.edu /** Debugging function to dump out the dependency graph. 2796735Sgblack@eecs.umich.edu */ 2806735Sgblack@eecs.umich.edu void dumpDependGraph(); 2816735Sgblack@eecs.umich.edu 2826735Sgblack@eecs.umich.edu /** Debugging function to dump all the list sizes, as well as print 2836735Sgblack@eecs.umich.edu * out the list of nonspeculative instructions. Should not be used 2847406SAli.Saidi@ARM.com * in any other capacity, but it has no harmful sideaffects. 2856735Sgblack@eecs.umich.edu */ 2866735Sgblack@eecs.umich.edu void dumpLists(); 2877360Sgblack@eecs.umich.edu 2886735Sgblack@eecs.umich.edu Stats::Scalar<> iqInstsAdded; 2897360Sgblack@eecs.umich.edu Stats::Scalar<> iqNonSpecInstsAdded; 2906735Sgblack@eecs.umich.edu// Stats::Scalar<> iqIntInstsAdded; 2916735Sgblack@eecs.umich.edu Stats::Scalar<> iqIntInstsIssued; 2926735Sgblack@eecs.umich.edu// Stats::Scalar<> iqFloatInstsAdded; 2936735Sgblack@eecs.umich.edu Stats::Scalar<> iqFloatInstsIssued; 2946735Sgblack@eecs.umich.edu// Stats::Scalar<> iqBranchInstsAdded; 2956735Sgblack@eecs.umich.edu Stats::Scalar<> iqBranchInstsIssued; 2967406SAli.Saidi@ARM.com// Stats::Scalar<> iqMemInstsAdded; 2976735Sgblack@eecs.umich.edu Stats::Scalar<> iqMemInstsIssued; 2986735Sgblack@eecs.umich.edu// Stats::Scalar<> iqMiscInstsAdded; 2996735Sgblack@eecs.umich.edu Stats::Scalar<> iqMiscInstsIssued; 3006735Sgblack@eecs.umich.edu Stats::Scalar<> iqSquashedInstsIssued; 3016735Sgblack@eecs.umich.edu Stats::Scalar<> iqLoopSquashStalls; 3026735Sgblack@eecs.umich.edu Stats::Scalar<> iqSquashedInstsExamined; 3037320Sgblack@eecs.umich.edu Stats::Scalar<> iqSquashedOperandsExamined; 3047320Sgblack@eecs.umich.edu Stats::Scalar<> iqSquashedNonSpecRemoved; 3057320Sgblack@eecs.umich.edu 3067320Sgblack@eecs.umich.edu}; 3077320Sgblack@eecs.umich.edu 3087320Sgblack@eecs.umich.edu#endif //__CPU_BETA_CPU_INST_QUEUE_HH__ 3097320Sgblack@eecs.umich.edu