inst_queue.hh revision 10510
12810SN/A/*
213932Snikos.nikoleris@arm.com * Copyright (c) 2011-2012, 2014 ARM Limited
38856Sandreas.hansson@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
48856Sandreas.hansson@arm.com * All rights reserved.
58856Sandreas.hansson@arm.com *
68856Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
78856Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
88856Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
98856Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
108856Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
118856Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
128856Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
138856Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
142810SN/A *
152810SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan
162810SN/A * All rights reserved.
172810SN/A *
182810SN/A * Redistribution and use in source and binary forms, with or without
192810SN/A * modification, are permitted provided that the following conditions are
202810SN/A * met: redistributions of source code must retain the above copyright
212810SN/A * notice, this list of conditions and the following disclaimer;
222810SN/A * redistributions in binary form must reproduce the above copyright
232810SN/A * notice, this list of conditions and the following disclaimer in the
242810SN/A * documentation and/or other materials provided with the distribution;
252810SN/A * neither the name of the copyright holders nor the names of its
262810SN/A * contributors may be used to endorse or promote products derived from
272810SN/A * this software without specific prior written permission.
282810SN/A *
292810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402810SN/A *
4112724Snikos.nikoleris@arm.com * Authors: Kevin Lim
422810SN/A */
432810SN/A
442810SN/A#ifndef __CPU_O3_INST_QUEUE_HH__
452810SN/A#define __CPU_O3_INST_QUEUE_HH__
462810SN/A
472810SN/A#include <list>
482810SN/A#include <map>
4911486Snikos.nikoleris@arm.com#include <queue>
5011486Snikos.nikoleris@arm.com#include <vector>
5112724Snikos.nikoleris@arm.com
5212724Snikos.nikoleris@arm.com#include "base/statistics.hh"
538232Snate@binkert.org#include "base/types.hh"
5412724Snikos.nikoleris@arm.com#include "cpu/o3/dep_graph.hh"
5513222Sodanrc@yahoo.com.br#include "cpu/inst_seq.hh"
5612724Snikos.nikoleris@arm.com#include "cpu/op_class.hh"
5711486Snikos.nikoleris@arm.com#include "cpu/timebuf.hh"
5812724Snikos.nikoleris@arm.com#include "sim/eventq.hh"
5912724Snikos.nikoleris@arm.com
6012724Snikos.nikoleris@arm.comstruct DerivO3CPUParams;
6113352Snikos.nikoleris@arm.comclass FUPool;
6212724Snikos.nikoleris@arm.comclass MemInterface;
6312724Snikos.nikoleris@arm.com
6412724Snikos.nikoleris@arm.com/**
6512724Snikos.nikoleris@arm.com * A standard instruction queue class.  It holds ready instructions, in
662810SN/A * order, in seperate priority queues to facilitate the scheduling of
672810SN/A * instructions.  The IQ uses a separate linked list to track dependencies.
682810SN/A * Similar to the rename map and the free list, it expects that
698856Sandreas.hansson@arm.com * floating point registers have their indices start after the integer
708856Sandreas.hansson@arm.com * registers (ie with 96 int and 96 fp registers, regs 0-95 are integer
718856Sandreas.hansson@arm.com * and 96-191 are fp).  This remains true even for both logical and
7213564Snikos.nikoleris@arm.com * physical register indices. The IQ depends on the memory dependence unit to
7313564Snikos.nikoleris@arm.com * track when memory operations are ready in terms of ordering; register
7412084Sspwilson2@wisc.edu * dependencies are tracked normally. Right now the IQ also handles the
7512084Sspwilson2@wisc.edu * execution timing; this is mainly to allow back-to-back scheduling without
768856Sandreas.hansson@arm.com * requiring IEW to be able to peek into the IQ. At the end of the execution
778856Sandreas.hansson@arm.com * latency, the instruction is put into the queue to execute, where it will
784475SN/A * have the execute() function called on it.
7911053Sandreas.hansson@arm.com * @todo: Make IQ able to handle multiple FU pools.
8013892Sgabeblack@google.com */
8112724Snikos.nikoleris@arm.comtemplate <class Impl>
8212724Snikos.nikoleris@arm.comclass InstructionQueue
8311377Sandreas.hansson@arm.com{
8411377Sandreas.hansson@arm.com  public:
8512724Snikos.nikoleris@arm.com    //Typedefs from the Impl.
8612724Snikos.nikoleris@arm.com    typedef typename Impl::O3CPU O3CPU;
8713352Snikos.nikoleris@arm.com    typedef typename Impl::DynInstPtr DynInstPtr;
8812724Snikos.nikoleris@arm.com
8912724Snikos.nikoleris@arm.com    typedef typename Impl::CPUPol::IEW IEW;
9012724Snikos.nikoleris@arm.com    typedef typename Impl::CPUPol::MemDepUnit MemDepUnit;
9112724Snikos.nikoleris@arm.com    typedef typename Impl::CPUPol::IssueStruct IssueStruct;
9212724Snikos.nikoleris@arm.com    typedef typename Impl::CPUPol::TimeStruct TimeStruct;
9311053Sandreas.hansson@arm.com
9411722Ssophiane.senni@gmail.com    // Typedef of iterator through the list of instructions.
9511722Ssophiane.senni@gmail.com    typedef typename std::list<DynInstPtr>::iterator ListIt;
9611722Ssophiane.senni@gmail.com
9711722Ssophiane.senni@gmail.com    /** FU completion event class. */
989263Smrinmoy.ghosh@arm.com    class FUCompletion : public Event {
9913418Sodanrc@yahoo.com.br      private:
1005034SN/A        /** Executing instruction. */
10111331Sandreas.hansson@arm.com        DynInstPtr inst;
10212724Snikos.nikoleris@arm.com
10310884Sandreas.hansson@arm.com        /** Index of the FU used for executing. */
1044626SN/A        int fuIdx;
10510360Sandreas.hansson@arm.com
10611484Snikos.nikoleris@arm.com        /** Pointer back to the instruction queue. */
1075034SN/A        InstructionQueue<Impl> *iqPtr;
1088883SAli.Saidi@ARM.com
1098833Sdam.sunwoo@arm.com        /** Should the FU be added to the list to be freed upon
1104458SN/A         * completing this event.
11111377Sandreas.hansson@arm.com         */
11211377Sandreas.hansson@arm.com        bool freeFU;
11311377Sandreas.hansson@arm.com
11411377Sandreas.hansson@arm.com      public:
11511377Sandreas.hansson@arm.com        /** Construct a FU completion event. */
11611377Sandreas.hansson@arm.com        FUCompletion(DynInstPtr &_inst, int fu_idx,
11711331Sandreas.hansson@arm.com                     InstructionQueue<Impl> *iq_ptr);
11811331Sandreas.hansson@arm.com
11912724Snikos.nikoleris@arm.com        virtual void process();
12012843Srmk35@cl.cam.ac.uk        virtual const char *description() const;
12112724Snikos.nikoleris@arm.com        void setFreeFU() { freeFU = true; }
12213419Sodanrc@yahoo.com.br    };
12312724Snikos.nikoleris@arm.com
12412724Snikos.nikoleris@arm.com    /** Constructs an IQ. */
12512724Snikos.nikoleris@arm.com    InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params);
12612724Snikos.nikoleris@arm.com
12712724Snikos.nikoleris@arm.com    /** Destructs the IQ. */
12812724Snikos.nikoleris@arm.com    ~InstructionQueue();
12912724Snikos.nikoleris@arm.com
1302810SN/A    /** Returns the name of the IQ. */
1312810SN/A    std::string name() const;
1323013SN/A
1338856Sandreas.hansson@arm.com    /** Registers statistics. */
1342810SN/A    void regStats();
1353013SN/A
13610714Sandreas.hansson@arm.com    /** Resets all instruction queue state. */
1372810SN/A    void resetState();
1389614Srene.dejong@arm.com
1399614Srene.dejong@arm.com    /** Sets active threads list. */
1409614Srene.dejong@arm.com    void setActiveThreads(std::list<ThreadID> *at_ptr);
14110345SCurtis.Dunham@arm.com
14210714Sandreas.hansson@arm.com    /** Sets the timer buffer between issue and execute. */
14310345SCurtis.Dunham@arm.com    void setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2eQueue);
1449614Srene.dejong@arm.com
1452810SN/A    /** Sets the global time buffer. */
1462810SN/A    void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
1472810SN/A
1488856Sandreas.hansson@arm.com    /** Determine if we are drained. */
1492810SN/A    bool isDrained() const;
1503013SN/A
15110714Sandreas.hansson@arm.com    /** Perform sanity checks after a drain. */
1523013SN/A    void drainSanityCheck() const;
1538856Sandreas.hansson@arm.com
15410714Sandreas.hansson@arm.com    /** Takes over execution from another CPU's thread. */
1558922Swilliam.wang@arm.com    void takeOverFrom();
1562897SN/A
1572810SN/A    /** Number of entries needed for given amount of threads. */
1582810SN/A    int entryAmount(ThreadID num_threads);
15910344Sandreas.hansson@arm.com
16010344Sandreas.hansson@arm.com    /** Resets max entries for all threads. */
16110344Sandreas.hansson@arm.com    void resetEntries();
16210714Sandreas.hansson@arm.com
16310344Sandreas.hansson@arm.com    /** Returns total number of free entries. */
16410344Sandreas.hansson@arm.com    unsigned numFreeEntries();
16510344Sandreas.hansson@arm.com
16610713Sandreas.hansson@arm.com    /** Returns number of free entries for a thread. */
16710344Sandreas.hansson@arm.com    unsigned numFreeEntries(ThreadID tid);
1682844SN/A
16912730Sodanrc@yahoo.com.br    /** Returns whether or not the IQ is full. */
17012730Sodanrc@yahoo.com.br    bool isFull();
17112730Sodanrc@yahoo.com.br
17212730Sodanrc@yahoo.com.br    /** Returns whether or not the IQ is full for a specific thread. */
17312730Sodanrc@yahoo.com.br    bool isFull(ThreadID tid);
17412730Sodanrc@yahoo.com.br
17512730Sodanrc@yahoo.com.br    /** Returns if there are any ready instructions in the IQ. */
17612730Sodanrc@yahoo.com.br    bool hasReadyInsts();
17712730Sodanrc@yahoo.com.br
17812730Sodanrc@yahoo.com.br    /** Inserts a new instruction into the IQ. */
1792810SN/A    void insert(DynInstPtr &new_inst);
1802858SN/A
1812858SN/A    /** Inserts a new, non-speculative instruction into the IQ. */
18212724Snikos.nikoleris@arm.com    void insertNonSpec(DynInstPtr &new_inst);
1838922Swilliam.wang@arm.com
18412724Snikos.nikoleris@arm.com    /** Inserts a memory or write barrier into the IQ to make sure
18512724Snikos.nikoleris@arm.com     *  loads and stores are ordered properly.
1862858SN/A     */
1872858SN/A    void insertBarrier(DynInstPtr &barr_inst);
18813784Sgabeblack@google.com
18913784Sgabeblack@google.com    /** Returns the oldest scheduled instruction, and removes it from
1908922Swilliam.wang@arm.com     * the list of instructions waiting to execute.
1918922Swilliam.wang@arm.com     */
19212724Snikos.nikoleris@arm.com    DynInstPtr getInstToExecute();
19313784Sgabeblack@google.com
19413784Sgabeblack@google.com    /** Gets a memory instruction that was referred due to a delayed DTB
1958922Swilliam.wang@arm.com     *  translation if it is now ready to execute.  NULL if none available.
19613892Sgabeblack@google.com     */
1978922Swilliam.wang@arm.com    DynInstPtr getDeferredMemInstToExecute();
1988922Swilliam.wang@arm.com
1994628SN/A    /** Gets a memory instruction that was blocked on the cache. NULL if none
20010821Sandreas.hansson@arm.com     *  available.
20110821Sandreas.hansson@arm.com     */
20210821Sandreas.hansson@arm.com    DynInstPtr getBlockedMemInstToExecute();
20310821Sandreas.hansson@arm.com
20410821Sandreas.hansson@arm.com    /**
20510821Sandreas.hansson@arm.com     * Records the instruction as the producer of a register without
20610821Sandreas.hansson@arm.com     * adding it to the rest of the IQ.
20710821Sandreas.hansson@arm.com     */
20810821Sandreas.hansson@arm.com    void recordProducer(DynInstPtr &inst)
20910821Sandreas.hansson@arm.com    { addToProducers(inst); }
21010821Sandreas.hansson@arm.com
2112858SN/A    /** Process FU completion event. */
21212724Snikos.nikoleris@arm.com    void processFUCompletion(DynInstPtr &inst, int fu_idx);
21312724Snikos.nikoleris@arm.com
21412724Snikos.nikoleris@arm.com    /**
21513745Sodanrc@yahoo.com.br     * Schedules ready instructions, adding the ready ones (oldest first) to
21613745Sodanrc@yahoo.com.br     * the queue to execute.
21713745Sodanrc@yahoo.com.br     */
21813745Sodanrc@yahoo.com.br    void scheduleReadyInsts();
21912724Snikos.nikoleris@arm.com
22012724Snikos.nikoleris@arm.com    /** Schedules a single specific non-speculative instruction. */
22112724Snikos.nikoleris@arm.com    void scheduleNonSpec(const InstSeqNum &inst);
22212724Snikos.nikoleris@arm.com
22312724Snikos.nikoleris@arm.com    /**
22413418Sodanrc@yahoo.com.br     * Commits all instructions up to and including the given sequence number,
22513418Sodanrc@yahoo.com.br     * for a specific thread.
22613564Snikos.nikoleris@arm.com     */
22712724Snikos.nikoleris@arm.com    void commit(const InstSeqNum &inst, ThreadID tid = 0);
22812724Snikos.nikoleris@arm.com
22912724Snikos.nikoleris@arm.com    /** Wakes all dependents of a completed instruction. */
23012724Snikos.nikoleris@arm.com    int wakeDependents(DynInstPtr &completed_inst);
23112724Snikos.nikoleris@arm.com
23212724Snikos.nikoleris@arm.com    /** Adds a ready memory instruction to the ready list. */
23312724Snikos.nikoleris@arm.com    void addReadyMemInst(DynInstPtr &ready_inst);
23412724Snikos.nikoleris@arm.com
23512724Snikos.nikoleris@arm.com    /**
23612724Snikos.nikoleris@arm.com     * Reschedules a memory instruction. It will be ready to issue once
23712724Snikos.nikoleris@arm.com     * replayMemInst() is called.
23812724Snikos.nikoleris@arm.com     */
23912724Snikos.nikoleris@arm.com    void rescheduleMemInst(DynInstPtr &resched_inst);
24012724Snikos.nikoleris@arm.com
24112724Snikos.nikoleris@arm.com    /** Replays a memory instruction. It must be rescheduled first. */
24212724Snikos.nikoleris@arm.com    void replayMemInst(DynInstPtr &replay_inst);
24313352Snikos.nikoleris@arm.com
24413352Snikos.nikoleris@arm.com    /** Completes a memory operation. */
24513352Snikos.nikoleris@arm.com    void completeMemInst(DynInstPtr &completed_inst);
24613352Snikos.nikoleris@arm.com
24713352Snikos.nikoleris@arm.com    /**
24813352Snikos.nikoleris@arm.com     * Defers a memory instruction when its DTB translation incurs a hw
24912724Snikos.nikoleris@arm.com     * page table walk.
25012724Snikos.nikoleris@arm.com     */
25112724Snikos.nikoleris@arm.com    void deferMemInst(DynInstPtr &deferred_inst);
25212724Snikos.nikoleris@arm.com
25312724Snikos.nikoleris@arm.com    /**  Defers a memory instruction when it is cache blocked. */
25412724Snikos.nikoleris@arm.com    void blockMemInst(DynInstPtr &blocked_inst);
25512724Snikos.nikoleris@arm.com
25612724Snikos.nikoleris@arm.com    /**  Notify instruction queue that a previous blockage has resolved */
25712724Snikos.nikoleris@arm.com    void cacheUnblocked();
25812724Snikos.nikoleris@arm.com
25912724Snikos.nikoleris@arm.com    /** Indicates an ordering violation between a store and a load. */
26012724Snikos.nikoleris@arm.com    void violation(DynInstPtr &store, DynInstPtr &faulting_load);
26112724Snikos.nikoleris@arm.com
26212724Snikos.nikoleris@arm.com    /**
26312724Snikos.nikoleris@arm.com     * Squashes instructions for a thread. Squashing information is obtained
26412724Snikos.nikoleris@arm.com     * from the time buffer.
26512724Snikos.nikoleris@arm.com     */
26612724Snikos.nikoleris@arm.com    void squash(ThreadID tid);
26712724Snikos.nikoleris@arm.com
26812724Snikos.nikoleris@arm.com    /** Returns the number of used entries for a thread. */
26912724Snikos.nikoleris@arm.com    unsigned getCount(ThreadID tid) { return count[tid]; };
27012724Snikos.nikoleris@arm.com
27112724Snikos.nikoleris@arm.com    /** Debug function to print all instructions. */
27212724Snikos.nikoleris@arm.com    void printInsts();
27312724Snikos.nikoleris@arm.com
27412724Snikos.nikoleris@arm.com  private:
27512724Snikos.nikoleris@arm.com    /** Does the actual squashing. */
27612724Snikos.nikoleris@arm.com    void doSquash(ThreadID tid);
27712724Snikos.nikoleris@arm.com
27812724Snikos.nikoleris@arm.com    /////////////////////////
27912724Snikos.nikoleris@arm.com    // Various pointers
28012724Snikos.nikoleris@arm.com    /////////////////////////
28112724Snikos.nikoleris@arm.com
28212724Snikos.nikoleris@arm.com    /** Pointer to the CPU. */
28312724Snikos.nikoleris@arm.com    O3CPU *cpu;
28412724Snikos.nikoleris@arm.com
28512724Snikos.nikoleris@arm.com    /** Cache interface. */
28612724Snikos.nikoleris@arm.com    MemInterface *dcacheInterface;
28712724Snikos.nikoleris@arm.com
28812724Snikos.nikoleris@arm.com    /** Pointer to IEW stage. */
28912724Snikos.nikoleris@arm.com    IEW *iewStage;
29012724Snikos.nikoleris@arm.com
29112724Snikos.nikoleris@arm.com    /** The memory dependence unit, which tracks/predicts memory dependences
29212724Snikos.nikoleris@arm.com     *  between instructions.
29312724Snikos.nikoleris@arm.com     */
29412724Snikos.nikoleris@arm.com    MemDepUnit memDepUnit[Impl::MaxThreads];
29512724Snikos.nikoleris@arm.com
29612724Snikos.nikoleris@arm.com    /** The queue to the execute stage.  Issued instructions will be written
29712724Snikos.nikoleris@arm.com     *  into it.
29812724Snikos.nikoleris@arm.com     */
29912724Snikos.nikoleris@arm.com    TimeBuffer<IssueStruct> *issueToExecuteQueue;
30012724Snikos.nikoleris@arm.com
30112724Snikos.nikoleris@arm.com    /** The backwards time buffer. */
30212724Snikos.nikoleris@arm.com    TimeBuffer<TimeStruct> *timeBuffer;
30312724Snikos.nikoleris@arm.com
30412724Snikos.nikoleris@arm.com    /** Wire to read information from timebuffer. */
30512724Snikos.nikoleris@arm.com    typename TimeBuffer<TimeStruct>::wire fromCommit;
30612724Snikos.nikoleris@arm.com
30712724Snikos.nikoleris@arm.com    /** Function unit pool. */
30812724Snikos.nikoleris@arm.com    FUPool *fuPool;
30912724Snikos.nikoleris@arm.com
31012724Snikos.nikoleris@arm.com    //////////////////////////////////////
31112724Snikos.nikoleris@arm.com    // Instruction lists, ready queues, and ordering
31212724Snikos.nikoleris@arm.com    //////////////////////////////////////
31312724Snikos.nikoleris@arm.com
31412724Snikos.nikoleris@arm.com    /** List of all the instructions in the IQ (some of which may be issued). */
31512724Snikos.nikoleris@arm.com    std::list<DynInstPtr> instList[Impl::MaxThreads];
31612724Snikos.nikoleris@arm.com
31712724Snikos.nikoleris@arm.com    /** List of instructions that are ready to be executed. */
31812724Snikos.nikoleris@arm.com    std::list<DynInstPtr> instsToExecute;
31912724Snikos.nikoleris@arm.com
32012724Snikos.nikoleris@arm.com    /** List of instructions waiting for their DTB translation to
32112724Snikos.nikoleris@arm.com     *  complete (hw page table walk in progress).
32212724Snikos.nikoleris@arm.com     */
32312724Snikos.nikoleris@arm.com    std::list<DynInstPtr> deferredMemInsts;
32412724Snikos.nikoleris@arm.com
32512724Snikos.nikoleris@arm.com    /** List of instructions that have been cache blocked. */
32612724Snikos.nikoleris@arm.com    std::list<DynInstPtr> blockedMemInsts;
32712724Snikos.nikoleris@arm.com
32812724Snikos.nikoleris@arm.com    /** List of instructions that were cache blocked, but a retry has been seen
32912724Snikos.nikoleris@arm.com     * since, so they can now be retried. May fail again go on the blocked list.
33012724Snikos.nikoleris@arm.com     */
33112724Snikos.nikoleris@arm.com    std::list<DynInstPtr> retryMemInsts;
33212724Snikos.nikoleris@arm.com
33312724Snikos.nikoleris@arm.com    /**
33412724Snikos.nikoleris@arm.com     * Struct for comparing entries to be added to the priority queue.
33512724Snikos.nikoleris@arm.com     * This gives reverse ordering to the instructions in terms of
33612724Snikos.nikoleris@arm.com     * sequence numbers: the instructions with smaller sequence
33712724Snikos.nikoleris@arm.com     * numbers (and hence are older) will be at the top of the
33812724Snikos.nikoleris@arm.com     * priority queue.
33912724Snikos.nikoleris@arm.com     */
34012724Snikos.nikoleris@arm.com    struct pqCompare {
34113418Sodanrc@yahoo.com.br        bool operator() (const DynInstPtr &lhs, const DynInstPtr &rhs) const
34212724Snikos.nikoleris@arm.com        {
34312724Snikos.nikoleris@arm.com            return lhs->seqNum > rhs->seqNum;
34412724Snikos.nikoleris@arm.com        }
34512724Snikos.nikoleris@arm.com    };
34612724Snikos.nikoleris@arm.com
34713418Sodanrc@yahoo.com.br    typedef std::priority_queue<DynInstPtr, std::vector<DynInstPtr>, pqCompare>
34812724Snikos.nikoleris@arm.com    ReadyInstQueue;
34912724Snikos.nikoleris@arm.com
35013747Sodanrc@yahoo.com.br    /** List of ready instructions, per op class.  They are separated by op
35113747Sodanrc@yahoo.com.br     *  class to allow for easy mapping to FUs.
35213747Sodanrc@yahoo.com.br     */
35313747Sodanrc@yahoo.com.br    ReadyInstQueue readyInsts[Num_OpClasses];
35412724Snikos.nikoleris@arm.com
35512724Snikos.nikoleris@arm.com    /** List of non-speculative instructions that will be scheduled
35612724Snikos.nikoleris@arm.com     *  once the IQ gets a signal from commit.  While it's redundant to
35712724Snikos.nikoleris@arm.com     *  have the key be a part of the value (the sequence number is stored
35813418Sodanrc@yahoo.com.br     *  inside of DynInst), when these instructions are woken up only
35912724Snikos.nikoleris@arm.com     *  the sequence number will be available.  Thus it is most efficient to be
36012724Snikos.nikoleris@arm.com     *  able to search by the sequence number alone.
36113746Sodanrc@yahoo.com.br     */
36212724Snikos.nikoleris@arm.com    std::map<InstSeqNum, DynInstPtr> nonSpecInsts;
36312724Snikos.nikoleris@arm.com
36412724Snikos.nikoleris@arm.com    typedef typename std::map<InstSeqNum, DynInstPtr>::iterator NonSpecMapIt;
36512724Snikos.nikoleris@arm.com
36613416Sjavier.bueno@metempsy.com    /** Entry for the list age ordering by op class. */
36713416Sjavier.bueno@metempsy.com    struct ListOrderEntry {
36813416Sjavier.bueno@metempsy.com        OpClass queueType;
36912724Snikos.nikoleris@arm.com        InstSeqNum oldestInst;
37013416Sjavier.bueno@metempsy.com    };
37113416Sjavier.bueno@metempsy.com
37212724Snikos.nikoleris@arm.com    /** List that contains the age order of the oldest instruction of each
37312724Snikos.nikoleris@arm.com     *  ready queue.  Used to select the oldest instruction available
37412724Snikos.nikoleris@arm.com     *  among op classes.
37512724Snikos.nikoleris@arm.com     *  @todo: Might be better to just move these entries around instead
37612724Snikos.nikoleris@arm.com     *  of creating new ones every time the position changes due to an
37712724Snikos.nikoleris@arm.com     *  instruction issuing.  Not sure std::list supports this.
37813416Sjavier.bueno@metempsy.com     */
37912724Snikos.nikoleris@arm.com    std::list<ListOrderEntry> listOrder;
38012724Snikos.nikoleris@arm.com
38113416Sjavier.bueno@metempsy.com    typedef typename std::list<ListOrderEntry>::iterator ListOrderIt;
38213416Sjavier.bueno@metempsy.com
38313416Sjavier.bueno@metempsy.com    /** Tracks if each ready queue is on the age order list. */
38413416Sjavier.bueno@metempsy.com    bool queueOnList[Num_OpClasses];
38513416Sjavier.bueno@metempsy.com
38613416Sjavier.bueno@metempsy.com    /** Iterators of each ready queue.  Points to their spot in the age order
38712724Snikos.nikoleris@arm.com     *  list.
38812724Snikos.nikoleris@arm.com     */
38912724Snikos.nikoleris@arm.com    ListOrderIt readyIt[Num_OpClasses];
39012724Snikos.nikoleris@arm.com
39112724Snikos.nikoleris@arm.com    /** Add an op class to the age order list. */
39212724Snikos.nikoleris@arm.com    void addToOrderList(OpClass op_class);
39312724Snikos.nikoleris@arm.com
39412724Snikos.nikoleris@arm.com    /**
39512724Snikos.nikoleris@arm.com     * Called when the oldest instruction has been removed from a ready queue;
39612724Snikos.nikoleris@arm.com     * this places that ready queue into the proper spot in the age order list.
39712724Snikos.nikoleris@arm.com     */
39812724Snikos.nikoleris@arm.com    void moveToYoungerInst(ListOrderIt age_order_it);
39913564Snikos.nikoleris@arm.com
40012724Snikos.nikoleris@arm.com    DependencyGraph<DynInstPtr> dependGraph;
40112724Snikos.nikoleris@arm.com
40212724Snikos.nikoleris@arm.com    //////////////////////////////////////
40312724Snikos.nikoleris@arm.com    // Various parameters
40412724Snikos.nikoleris@arm.com    //////////////////////////////////////
40512724Snikos.nikoleris@arm.com
40612724Snikos.nikoleris@arm.com    /** IQ Resource Sharing Policy */
40712724Snikos.nikoleris@arm.com    enum IQPolicy {
40812724Snikos.nikoleris@arm.com        Dynamic,
40912724Snikos.nikoleris@arm.com        Partitioned,
41012724Snikos.nikoleris@arm.com        Threshold
41112724Snikos.nikoleris@arm.com    };
41212724Snikos.nikoleris@arm.com
41312724Snikos.nikoleris@arm.com    /** IQ sharing policy for SMT. */
41412724Snikos.nikoleris@arm.com    IQPolicy iqPolicy;
41512724Snikos.nikoleris@arm.com
41612724Snikos.nikoleris@arm.com    /** Number of Total Threads*/
41712724Snikos.nikoleris@arm.com    ThreadID numThreads;
41812724Snikos.nikoleris@arm.com
41912724Snikos.nikoleris@arm.com    /** Pointer to list of active threads. */
42012724Snikos.nikoleris@arm.com    std::list<ThreadID> *activeThreads;
42112724Snikos.nikoleris@arm.com
42212724Snikos.nikoleris@arm.com    /** Per Thread IQ count */
42312724Snikos.nikoleris@arm.com    unsigned count[Impl::MaxThreads];
42412724Snikos.nikoleris@arm.com
42512724Snikos.nikoleris@arm.com    /** Max IQ Entries Per Thread */
42612724Snikos.nikoleris@arm.com    unsigned maxEntries[Impl::MaxThreads];
42712724Snikos.nikoleris@arm.com
42812724Snikos.nikoleris@arm.com    /** Number of free IQ entries left. */
42912724Snikos.nikoleris@arm.com    unsigned freeEntries;
43012724Snikos.nikoleris@arm.com
43112724Snikos.nikoleris@arm.com    /** The number of entries in the instruction queue. */
43212724Snikos.nikoleris@arm.com    unsigned numEntries;
43312724Snikos.nikoleris@arm.com
43412724Snikos.nikoleris@arm.com    /** The total number of instructions that can be issued in one cycle. */
43512724Snikos.nikoleris@arm.com    unsigned totalWidth;
43612724Snikos.nikoleris@arm.com
43712724Snikos.nikoleris@arm.com    /** The number of physical registers in the CPU. */
43812724Snikos.nikoleris@arm.com    unsigned numPhysRegs;
43912724Snikos.nikoleris@arm.com
44012724Snikos.nikoleris@arm.com    /** Delay between commit stage and the IQ.
44112724Snikos.nikoleris@arm.com     *  @todo: Make there be a distinction between the delays within IEW.
44213859Sodanrc@yahoo.com.br     */
44312724Snikos.nikoleris@arm.com    Cycles commitToIEWDelay;
44412724Snikos.nikoleris@arm.com
44512724Snikos.nikoleris@arm.com    /** The sequence number of the squashed instruction. */
44612724Snikos.nikoleris@arm.com    InstSeqNum squashedSeqNum[Impl::MaxThreads];
44712724Snikos.nikoleris@arm.com
44812724Snikos.nikoleris@arm.com    /** A cache of the recently woken registers.  It is 1 if the register
44912724Snikos.nikoleris@arm.com     *  has been woken up recently, and 0 if the register has been added
45012724Snikos.nikoleris@arm.com     *  to the dependency graph and has not yet received its value.  It
45112724Snikos.nikoleris@arm.com     *  is basically a secondary scoreboard, and should pretty much mirror
45212724Snikos.nikoleris@arm.com     *  the scoreboard that exists in the rename map.
45312724Snikos.nikoleris@arm.com     */
45412724Snikos.nikoleris@arm.com    std::vector<bool> regScoreboard;
45512724Snikos.nikoleris@arm.com
45612724Snikos.nikoleris@arm.com    /** Adds an instruction to the dependency graph, as a consumer. */
45712724Snikos.nikoleris@arm.com    bool addToDependents(DynInstPtr &new_inst);
45812724Snikos.nikoleris@arm.com
45913350Snikos.nikoleris@arm.com    /** Adds an instruction to the dependency graph, as a producer. */
46013350Snikos.nikoleris@arm.com    void addToProducers(DynInstPtr &new_inst);
46113350Snikos.nikoleris@arm.com
46213350Snikos.nikoleris@arm.com    /** Moves an instruction to the ready queue if it is ready. */
46313350Snikos.nikoleris@arm.com    void addIfReady(DynInstPtr &inst);
46413350Snikos.nikoleris@arm.com
46512724Snikos.nikoleris@arm.com    /** Debugging function to count how many entries are in the IQ.  It does
46612724Snikos.nikoleris@arm.com     *  a linear walk through the instructions, so do not call this function
46712724Snikos.nikoleris@arm.com     *  during normal execution.
46812724Snikos.nikoleris@arm.com     */
46912724Snikos.nikoleris@arm.com    int countInsts();
47012724Snikos.nikoleris@arm.com
47112724Snikos.nikoleris@arm.com    /** Debugging function to dump all the list sizes, as well as print
47213352Snikos.nikoleris@arm.com     *  out the list of nonspeculative instructions.  Should not be used
47313352Snikos.nikoleris@arm.com     *  in any other capacity, but it has no harmful sideaffects.
47413352Snikos.nikoleris@arm.com     */
47512724Snikos.nikoleris@arm.com    void dumpLists();
47613717Sivan.pizarro@metempsy.com
47712724Snikos.nikoleris@arm.com    /** Debugging function to dump out all instructions that are in the
47812724Snikos.nikoleris@arm.com     *  IQ.
47912724Snikos.nikoleris@arm.com     */
48012724Snikos.nikoleris@arm.com    void dumpInsts();
48112724Snikos.nikoleris@arm.com
48212724Snikos.nikoleris@arm.com    /** Stat for number of instructions added. */
48312794Snikos.nikoleris@arm.com    Stats::Scalar iqInstsAdded;
48412794Snikos.nikoleris@arm.com    /** Stat for number of non-speculative instructions added. */
48512794Snikos.nikoleris@arm.com    Stats::Scalar iqNonSpecInstsAdded;
48612794Snikos.nikoleris@arm.com
48712794Snikos.nikoleris@arm.com    Stats::Scalar iqInstsIssued;
48812794Snikos.nikoleris@arm.com    /** Stat for number of integer instructions issued. */
48912724Snikos.nikoleris@arm.com    Stats::Scalar iqIntInstsIssued;
49012724Snikos.nikoleris@arm.com    /** Stat for number of floating point instructions issued. */
49112724Snikos.nikoleris@arm.com    Stats::Scalar iqFloatInstsIssued;
49212724Snikos.nikoleris@arm.com    /** Stat for number of branch instructions issued. */
49312724Snikos.nikoleris@arm.com    Stats::Scalar iqBranchInstsIssued;
49412724Snikos.nikoleris@arm.com    /** Stat for number of memory instructions issued. */
49512724Snikos.nikoleris@arm.com    Stats::Scalar iqMemInstsIssued;
49612724Snikos.nikoleris@arm.com    /** Stat for number of miscellaneous instructions issued. */
49712724Snikos.nikoleris@arm.com    Stats::Scalar iqMiscInstsIssued;
49813478Sodanrc@yahoo.com.br    /** Stat for number of squashed instructions that were ready to issue. */
49912724Snikos.nikoleris@arm.com    Stats::Scalar iqSquashedInstsIssued;
50012724Snikos.nikoleris@arm.com    /** Stat for number of squashed instructions examined when squashing. */
50112724Snikos.nikoleris@arm.com    Stats::Scalar iqSquashedInstsExamined;
50212724Snikos.nikoleris@arm.com    /** Stat for number of squashed instruction operands examined when
50312724Snikos.nikoleris@arm.com     * squashing.
50412724Snikos.nikoleris@arm.com     */
50512724Snikos.nikoleris@arm.com    Stats::Scalar iqSquashedOperandsExamined;
50612724Snikos.nikoleris@arm.com    /** Stat for number of non-speculative instructions removed due to a squash.
50712724Snikos.nikoleris@arm.com     */
50812724Snikos.nikoleris@arm.com    Stats::Scalar iqSquashedNonSpecRemoved;
50912724Snikos.nikoleris@arm.com    // Also include number of instructions rescheduled and replayed.
51012724Snikos.nikoleris@arm.com
51112724Snikos.nikoleris@arm.com    /** Distribution of number of instructions in the queue.
51212724Snikos.nikoleris@arm.com     * @todo: Need to create struct to track the entry time for each
51312724Snikos.nikoleris@arm.com     * instruction. */
51412724Snikos.nikoleris@arm.com//    Stats::VectorDistribution queueResDist;
51512724Snikos.nikoleris@arm.com    /** Distribution of the number of instructions issued. */
51612724Snikos.nikoleris@arm.com    Stats::Distribution numIssuedDist;
51712724Snikos.nikoleris@arm.com    /** Distribution of the cycles it takes to issue an instruction.
51812724Snikos.nikoleris@arm.com     * @todo: Need to create struct to track the ready time for each
51912724Snikos.nikoleris@arm.com     * instruction. */
52012724Snikos.nikoleris@arm.com//    Stats::VectorDistribution issueDelayDist;
52112724Snikos.nikoleris@arm.com
52212724Snikos.nikoleris@arm.com    /** Number of times an instruction could not be issued because a
52312724Snikos.nikoleris@arm.com     * FU was busy.
52412724Snikos.nikoleris@arm.com     */
52512724Snikos.nikoleris@arm.com    Stats::Vector statFuBusy;
52612724Snikos.nikoleris@arm.com//    Stats::Vector dist_unissued;
52712724Snikos.nikoleris@arm.com    /** Stat for total number issued for each instruction type. */
52812724Snikos.nikoleris@arm.com    Stats::Vector2d statIssuedInstType;
52912724Snikos.nikoleris@arm.com
53012724Snikos.nikoleris@arm.com    /** Number of instructions issued per cycle. */
53112724Snikos.nikoleris@arm.com    Stats::Formula issueRate;
53212724Snikos.nikoleris@arm.com
53312724Snikos.nikoleris@arm.com    /** Number of times the FU was busy. */
53412724Snikos.nikoleris@arm.com    Stats::Vector fuBusy;
53512724Snikos.nikoleris@arm.com    /** Number of times the FU was busy per instruction issued. */
53612724Snikos.nikoleris@arm.com    Stats::Formula fuBusyRate;
53712724Snikos.nikoleris@arm.com   public:
53812724Snikos.nikoleris@arm.com    Stats::Scalar intInstQueueReads;
53912724Snikos.nikoleris@arm.com    Stats::Scalar intInstQueueWrites;
54012724Snikos.nikoleris@arm.com    Stats::Scalar intInstQueueWakeupAccesses;
54112724Snikos.nikoleris@arm.com    Stats::Scalar fpInstQueueReads;
54212724Snikos.nikoleris@arm.com    Stats::Scalar fpInstQueueWrites;
54312724Snikos.nikoleris@arm.com    Stats::Scalar fpInstQueueWakeupQccesses;
54412724Snikos.nikoleris@arm.com
54512724Snikos.nikoleris@arm.com    Stats::Scalar intAluAccesses;
54612724Snikos.nikoleris@arm.com    Stats::Scalar fpAluAccesses;
54712724Snikos.nikoleris@arm.com};
54812724Snikos.nikoleris@arm.com
54913412Snikos.nikoleris@arm.com#endif //__CPU_O3_INST_QUEUE_HH__
55013412Snikos.nikoleris@arm.com