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 &params);
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