fetch.hh revision 10023:91faf6649de0
112647Santhony.gutierrez@amd.com/*
212647Santhony.gutierrez@amd.com * Copyright (c) 2010-2012 ARM Limited
311308Santhony.gutierrez@amd.com * All rights reserved
412647Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * The license below extends only to copyright in the software and shall
612647Santhony.gutierrez@amd.com * not be construed as granting a license to any other intellectual
712647Santhony.gutierrez@amd.com * property including but not limited to intellectual property relating
811308Santhony.gutierrez@amd.com * to a hardware implementation of the functionality of the software
912647Santhony.gutierrez@amd.com * licensed hereunder.  You may use the software subject to the license
1012647Santhony.gutierrez@amd.com * terms below provided that you ensure that this notice is replicated
1111308Santhony.gutierrez@amd.com * unmodified and in its entirety in all distributions of the software,
1212647Santhony.gutierrez@amd.com * modified or unmodified, in source code or in binary form.
1312647Santhony.gutierrez@amd.com *
1412647Santhony.gutierrez@amd.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
1511308Santhony.gutierrez@amd.com * All rights reserved.
1612647Santhony.gutierrez@amd.com *
1712647Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
1812647Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are
1911308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright
2012647Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer;
2112647Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright
2212647Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the
2312647Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution;
2412647Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its
2512647Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
2612647Santhony.gutierrez@amd.com * this software without specific prior written permission.
2712647Santhony.gutierrez@amd.com *
2812647Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2912647Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3012647Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3111308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3212647Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3311308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3411308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3511308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3611308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3711308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3813400Sodanrc@yahoo.com.br * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3911308Santhony.gutierrez@amd.com *
4011308Santhony.gutierrez@amd.com * Authors: Kevin Lim
4111308Santhony.gutierrez@amd.com *          Korey Sewell
4213400Sodanrc@yahoo.com.br */
4313400Sodanrc@yahoo.com.br
4411670Sandreas.hansson@arm.com#ifndef __CPU_O3_FETCH_HH__
4511670Sandreas.hansson@arm.com#define __CPU_O3_FETCH_HH__
4611308Santhony.gutierrez@amd.com
4711308Santhony.gutierrez@amd.com#include "arch/decoder.hh"
4811308Santhony.gutierrez@amd.com#include "arch/utility.hh"
4911308Santhony.gutierrez@amd.com#include "base/statistics.hh"
5011308Santhony.gutierrez@amd.com#include "config/the_isa.hh"
5111308Santhony.gutierrez@amd.com#include "cpu/pc_event.hh"
5211308Santhony.gutierrez@amd.com#include "cpu/pred/bpred_unit.hh"
5311308Santhony.gutierrez@amd.com#include "cpu/timebuf.hh"
5411308Santhony.gutierrez@amd.com#include "cpu/translation.hh"
5511308Santhony.gutierrez@amd.com#include "mem/packet.hh"
5611308Santhony.gutierrez@amd.com#include "mem/port.hh"
5711308Santhony.gutierrez@amd.com#include "sim/eventq.hh"
5811308Santhony.gutierrez@amd.com#include "sim/probe/probe.hh"
5911308Santhony.gutierrez@amd.com
6011308Santhony.gutierrez@amd.comstruct DerivO3CPUParams;
6111308Santhony.gutierrez@amd.com
6211308Santhony.gutierrez@amd.com/**
6311308Santhony.gutierrez@amd.com * DefaultFetch class handles both single threaded and SMT fetch. Its
6411308Santhony.gutierrez@amd.com * width is specified by the parameters; each cycle it tries to fetch
6511308Santhony.gutierrez@amd.com * that many instructions. It supports using a branch predictor to
6611308Santhony.gutierrez@amd.com * predict direction and targets.
6711308Santhony.gutierrez@amd.com * It supports the idling functionality of the CPU by indicating to
6811308Santhony.gutierrez@amd.com * the CPU when it is active and inactive.
6911308Santhony.gutierrez@amd.com */
7011308Santhony.gutierrez@amd.comtemplate <class Impl>
7111308Santhony.gutierrez@amd.comclass DefaultFetch
7211308Santhony.gutierrez@amd.com{
7311308Santhony.gutierrez@amd.com  public:
7411308Santhony.gutierrez@amd.com    /** Typedefs from Impl. */
7511308Santhony.gutierrez@amd.com    typedef typename Impl::CPUPol CPUPol;
7611308Santhony.gutierrez@amd.com    typedef typename Impl::DynInst DynInst;
7711308Santhony.gutierrez@amd.com    typedef typename Impl::DynInstPtr DynInstPtr;
7811308Santhony.gutierrez@amd.com    typedef typename Impl::O3CPU O3CPU;
7911308Santhony.gutierrez@amd.com
8011308Santhony.gutierrez@amd.com    /** Typedefs from the CPU policy. */
8111308Santhony.gutierrez@amd.com    typedef typename CPUPol::FetchStruct FetchStruct;
8211308Santhony.gutierrez@amd.com    typedef typename CPUPol::TimeStruct TimeStruct;
8311308Santhony.gutierrez@amd.com
8411308Santhony.gutierrez@amd.com    /** Typedefs from ISA. */
8511308Santhony.gutierrez@amd.com    typedef TheISA::MachInst MachInst;
8611308Santhony.gutierrez@amd.com    typedef TheISA::ExtMachInst ExtMachInst;
8711308Santhony.gutierrez@amd.com
8811308Santhony.gutierrez@amd.com    class FetchTranslation : public BaseTLB::Translation
8911308Santhony.gutierrez@amd.com    {
9011308Santhony.gutierrez@amd.com      protected:
9111308Santhony.gutierrez@amd.com        DefaultFetch<Impl> *fetch;
9211308Santhony.gutierrez@amd.com
9311308Santhony.gutierrez@amd.com      public:
9411308Santhony.gutierrez@amd.com        FetchTranslation(DefaultFetch<Impl> *_fetch)
9511308Santhony.gutierrez@amd.com            : fetch(_fetch)
9611308Santhony.gutierrez@amd.com        {}
9711308Santhony.gutierrez@amd.com
9811308Santhony.gutierrez@amd.com        void
9911308Santhony.gutierrez@amd.com        markDelayed()
10011308Santhony.gutierrez@amd.com        {}
10111308Santhony.gutierrez@amd.com
10211308Santhony.gutierrez@amd.com        void
10311308Santhony.gutierrez@amd.com        finish(Fault fault, RequestPtr req, ThreadContext *tc,
10411308Santhony.gutierrez@amd.com               BaseTLB::Mode mode)
10511308Santhony.gutierrez@amd.com        {
10611308Santhony.gutierrez@amd.com            assert(mode == BaseTLB::Execute);
10711308Santhony.gutierrez@amd.com            fetch->finishTranslation(fault, req);
10811308Santhony.gutierrez@amd.com            delete this;
10911308Santhony.gutierrez@amd.com        }
11011308Santhony.gutierrez@amd.com    };
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com  private:
11311308Santhony.gutierrez@amd.com    /* Event to delay delivery of a fetch translation result in case of
11411308Santhony.gutierrez@amd.com     * a fault and the nop to carry the fault cannot be generated
11511308Santhony.gutierrez@amd.com     * immediately */
11611308Santhony.gutierrez@amd.com    class FinishTranslationEvent : public Event
11711308Santhony.gutierrez@amd.com    {
11811308Santhony.gutierrez@amd.com      private:
11911308Santhony.gutierrez@amd.com        DefaultFetch<Impl> *fetch;
12011308Santhony.gutierrez@amd.com        Fault fault;
12111308Santhony.gutierrez@amd.com        RequestPtr req;
12211308Santhony.gutierrez@amd.com
12311308Santhony.gutierrez@amd.com      public:
12411308Santhony.gutierrez@amd.com        FinishTranslationEvent(DefaultFetch<Impl> *_fetch)
12511308Santhony.gutierrez@amd.com            : fetch(_fetch)
12611308Santhony.gutierrez@amd.com        {}
12711308Santhony.gutierrez@amd.com
12811308Santhony.gutierrez@amd.com        void setFault(Fault _fault)
12911308Santhony.gutierrez@amd.com        {
13011308Santhony.gutierrez@amd.com            fault = _fault;
13111308Santhony.gutierrez@amd.com        }
13211308Santhony.gutierrez@amd.com
13311308Santhony.gutierrez@amd.com        void setReq(RequestPtr _req)
13411308Santhony.gutierrez@amd.com        {
13511308Santhony.gutierrez@amd.com            req = _req;
13611308Santhony.gutierrez@amd.com        }
13711308Santhony.gutierrez@amd.com
13811308Santhony.gutierrez@amd.com        /** Process the delayed finish translation */
13911308Santhony.gutierrez@amd.com        void process()
14011308Santhony.gutierrez@amd.com        {
14111308Santhony.gutierrez@amd.com            assert(fetch->numInst < fetch->fetchWidth);
14211308Santhony.gutierrez@amd.com            fetch->finishTranslation(fault, req);
14311308Santhony.gutierrez@amd.com        }
14411308Santhony.gutierrez@amd.com
14511308Santhony.gutierrez@amd.com        const char *description() const
14611308Santhony.gutierrez@amd.com        {
14711308Santhony.gutierrez@amd.com            return "FullO3CPU FetchFinishTranslation";
14811308Santhony.gutierrez@amd.com        }
14911308Santhony.gutierrez@amd.com      };
15011308Santhony.gutierrez@amd.com
15111308Santhony.gutierrez@amd.com  public:
15211308Santhony.gutierrez@amd.com    /** Overall fetch status. Used to determine if the CPU can
15311308Santhony.gutierrez@amd.com     * deschedule itsef due to a lack of activity.
15411308Santhony.gutierrez@amd.com     */
15511308Santhony.gutierrez@amd.com    enum FetchStatus {
15611308Santhony.gutierrez@amd.com        Active,
15711308Santhony.gutierrez@amd.com        Inactive
15811308Santhony.gutierrez@amd.com    };
15911308Santhony.gutierrez@amd.com
16011308Santhony.gutierrez@amd.com    /** Individual thread status. */
16111308Santhony.gutierrez@amd.com    enum ThreadStatus {
16211308Santhony.gutierrez@amd.com        Running,
16311308Santhony.gutierrez@amd.com        Idle,
16411308Santhony.gutierrez@amd.com        Squashing,
16511308Santhony.gutierrez@amd.com        Blocked,
16611308Santhony.gutierrez@amd.com        Fetching,
16711308Santhony.gutierrez@amd.com        TrapPending,
16811308Santhony.gutierrez@amd.com        QuiescePending,
16911308Santhony.gutierrez@amd.com        ItlbWait,
17011308Santhony.gutierrez@amd.com        IcacheWaitResponse,
17111308Santhony.gutierrez@amd.com        IcacheWaitRetry,
17211308Santhony.gutierrez@amd.com        IcacheAccessComplete,
17311308Santhony.gutierrez@amd.com        NoGoodAddr
17411308Santhony.gutierrez@amd.com    };
17511308Santhony.gutierrez@amd.com
17611308Santhony.gutierrez@amd.com    /** Fetching Policy, Add new policies here.*/
17711308Santhony.gutierrez@amd.com    enum FetchPriority {
17811308Santhony.gutierrez@amd.com        SingleThread,
17911308Santhony.gutierrez@amd.com        RoundRobin,
18011308Santhony.gutierrez@amd.com        Branch,
18111308Santhony.gutierrez@amd.com        IQ,
18211308Santhony.gutierrez@amd.com        LSQ
18311308Santhony.gutierrez@amd.com    };
18411308Santhony.gutierrez@amd.com
18511308Santhony.gutierrez@amd.com  private:
18611308Santhony.gutierrez@amd.com    /** Fetch status. */
18711308Santhony.gutierrez@amd.com    FetchStatus _status;
18811308Santhony.gutierrez@amd.com
18911308Santhony.gutierrez@amd.com    /** Per-thread status. */
19011308Santhony.gutierrez@amd.com    ThreadStatus fetchStatus[Impl::MaxThreads];
19111308Santhony.gutierrez@amd.com
19211308Santhony.gutierrez@amd.com    /** Fetch policy. */
19311308Santhony.gutierrez@amd.com    FetchPriority fetchPolicy;
19411308Santhony.gutierrez@amd.com
19511308Santhony.gutierrez@amd.com    /** List that has the threads organized by priority. */
19611308Santhony.gutierrez@amd.com    std::list<ThreadID> priorityList;
19711308Santhony.gutierrez@amd.com
19811308Santhony.gutierrez@amd.com    /** Probe points. */
19911308Santhony.gutierrez@amd.com    ProbePointArg<DynInstPtr> *ppFetch;
20011308Santhony.gutierrez@amd.com
20111308Santhony.gutierrez@amd.com  public:
20211308Santhony.gutierrez@amd.com    /** DefaultFetch constructor. */
20311308Santhony.gutierrez@amd.com    DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params);
20411308Santhony.gutierrez@amd.com
20511308Santhony.gutierrez@amd.com    /** Returns the name of fetch. */
20611308Santhony.gutierrez@amd.com    std::string name() const;
20711308Santhony.gutierrez@amd.com
20811308Santhony.gutierrez@amd.com    /** Registers statistics. */
20911308Santhony.gutierrez@amd.com    void regStats();
21011308Santhony.gutierrez@amd.com
21111308Santhony.gutierrez@amd.com    /** Registers probes. */
21211308Santhony.gutierrez@amd.com    void regProbePoints();
21311308Santhony.gutierrez@amd.com
21411308Santhony.gutierrez@amd.com    /** Sets the main backwards communication time buffer pointer. */
21511308Santhony.gutierrez@amd.com    void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
21611308Santhony.gutierrez@amd.com
21711308Santhony.gutierrez@amd.com    /** Sets pointer to list of active threads. */
21811308Santhony.gutierrez@amd.com    void setActiveThreads(std::list<ThreadID> *at_ptr);
21911308Santhony.gutierrez@amd.com
22011308Santhony.gutierrez@amd.com    /** Sets pointer to time buffer used to communicate to the next stage. */
22111308Santhony.gutierrez@amd.com    void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
22211308Santhony.gutierrez@amd.com
22311308Santhony.gutierrez@amd.com    /** Initialize stage. */
22411308Santhony.gutierrez@amd.com    void startupStage();
22511308Santhony.gutierrez@amd.com
22611308Santhony.gutierrez@amd.com    /** Handles retrying the fetch access. */
22711308Santhony.gutierrez@amd.com    void recvRetry();
22811308Santhony.gutierrez@amd.com
22911308Santhony.gutierrez@amd.com    /** Processes cache completion event. */
23011308Santhony.gutierrez@amd.com    void processCacheCompletion(PacketPtr pkt);
23111308Santhony.gutierrez@amd.com
23211308Santhony.gutierrez@amd.com    /** Resume after a drain. */
23311308Santhony.gutierrez@amd.com    void drainResume();
23411308Santhony.gutierrez@amd.com
23511308Santhony.gutierrez@amd.com    /** Perform sanity checks after a drain. */
23611308Santhony.gutierrez@amd.com    void drainSanityCheck() const;
23711308Santhony.gutierrez@amd.com
23811308Santhony.gutierrez@amd.com    /** Has the stage drained? */
23911308Santhony.gutierrez@amd.com    bool isDrained() const;
24011308Santhony.gutierrez@amd.com
24111308Santhony.gutierrez@amd.com    /** Takes over from another CPU's thread. */
24211308Santhony.gutierrez@amd.com    void takeOverFrom();
24311308Santhony.gutierrez@amd.com
24411308Santhony.gutierrez@amd.com    /**
24511308Santhony.gutierrez@amd.com     * Stall the fetch stage after reaching a safe drain point.
24611308Santhony.gutierrez@amd.com     *
24711308Santhony.gutierrez@amd.com     * The CPU uses this method to stop fetching instructions from a
24811308Santhony.gutierrez@amd.com     * thread that has been drained. The drain stall is different from
24911308Santhony.gutierrez@amd.com     * all other stalls in that it is signaled instantly from the
25011308Santhony.gutierrez@amd.com     * commit stage (without the normal communication delay) when it
25111308Santhony.gutierrez@amd.com     * has reached a safe point to drain from.
25211308Santhony.gutierrez@amd.com     */
25311308Santhony.gutierrez@amd.com    void drainStall(ThreadID tid);
25411308Santhony.gutierrez@amd.com
25511308Santhony.gutierrez@amd.com    /** Tells fetch to wake up from a quiesce instruction. */
25611308Santhony.gutierrez@amd.com    void wakeFromQuiesce();
25711308Santhony.gutierrez@amd.com
25811308Santhony.gutierrez@amd.com  private:
25911308Santhony.gutierrez@amd.com    /** Reset this pipeline stage */
26011308Santhony.gutierrez@amd.com    void resetStage();
26111308Santhony.gutierrez@amd.com
26211308Santhony.gutierrez@amd.com    /** Changes the status of this stage to active, and indicates this
26311308Santhony.gutierrez@amd.com     * to the CPU.
26411308Santhony.gutierrez@amd.com     */
26511308Santhony.gutierrez@amd.com    inline void switchToActive();
26611308Santhony.gutierrez@amd.com
26711308Santhony.gutierrez@amd.com    /** Changes the status of this stage to inactive, and indicates
26811308Santhony.gutierrez@amd.com     * this to the CPU.
26911308Santhony.gutierrez@amd.com     */
27011308Santhony.gutierrez@amd.com    inline void switchToInactive();
27111308Santhony.gutierrez@amd.com
27211308Santhony.gutierrez@amd.com    /**
27311308Santhony.gutierrez@amd.com     * Looks up in the branch predictor to see if the next PC should be
27411308Santhony.gutierrez@amd.com     * either next PC+=MachInst or a branch target.
27511308Santhony.gutierrez@amd.com     * @param next_PC Next PC variable passed in by reference.  It is
27611308Santhony.gutierrez@amd.com     * expected to be set to the current PC; it will be updated with what
27711308Santhony.gutierrez@amd.com     * the next PC will be.
27811308Santhony.gutierrez@amd.com     * @param next_NPC Used for ISAs which use delay slots.
27911308Santhony.gutierrez@amd.com     * @return Whether or not a branch was predicted as taken.
28011308Santhony.gutierrez@amd.com     */
28111308Santhony.gutierrez@amd.com    bool lookupAndUpdateNextPC(DynInstPtr &inst, TheISA::PCState &pc);
28211308Santhony.gutierrez@amd.com
28311308Santhony.gutierrez@amd.com    /**
28411308Santhony.gutierrez@amd.com     * Fetches the cache line that contains the fetch PC.  Returns any
28511308Santhony.gutierrez@amd.com     * fault that happened.  Puts the data into the class variable
28611308Santhony.gutierrez@amd.com     * fetchBuffer, which may not hold the entire fetched cache line.
28711308Santhony.gutierrez@amd.com     * @param vaddr The memory address that is being fetched from.
28811308Santhony.gutierrez@amd.com     * @param ret_fault The fault reference that will be set to the result of
28911308Santhony.gutierrez@amd.com     * the icache access.
29011308Santhony.gutierrez@amd.com     * @param tid Thread id.
29111308Santhony.gutierrez@amd.com     * @param pc The actual PC of the current instruction.
29211308Santhony.gutierrez@amd.com     * @return Any fault that occured.
29311308Santhony.gutierrez@amd.com     */
29411308Santhony.gutierrez@amd.com    bool fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc);
29511308Santhony.gutierrez@amd.com    void finishTranslation(Fault fault, RequestPtr mem_req);
29611308Santhony.gutierrez@amd.com
29711308Santhony.gutierrez@amd.com
29811308Santhony.gutierrez@amd.com    /** Check if an interrupt is pending and that we need to handle
29911308Santhony.gutierrez@amd.com     */
30011308Santhony.gutierrez@amd.com    bool
30111308Santhony.gutierrez@amd.com    checkInterrupt(Addr pc)
30211308Santhony.gutierrez@amd.com    {
30311308Santhony.gutierrez@amd.com        return (interruptPending && (THE_ISA != ALPHA_ISA || !(pc & 0x3)));
30411308Santhony.gutierrez@amd.com    }
30511308Santhony.gutierrez@amd.com
30611308Santhony.gutierrez@amd.com    /** Squashes a specific thread and resets the PC. */
30711308Santhony.gutierrez@amd.com    inline void doSquash(const TheISA::PCState &newPC,
30811308Santhony.gutierrez@amd.com                         const DynInstPtr squashInst, ThreadID tid);
30911308Santhony.gutierrez@amd.com
31011308Santhony.gutierrez@amd.com    /** Squashes a specific thread and resets the PC. Also tells the CPU to
31111308Santhony.gutierrez@amd.com     * remove any instructions between fetch and decode that should be sqaushed.
31211308Santhony.gutierrez@amd.com     */
31311308Santhony.gutierrez@amd.com    void squashFromDecode(const TheISA::PCState &newPC,
31411308Santhony.gutierrez@amd.com                          const DynInstPtr squashInst,
31511308Santhony.gutierrez@amd.com                          const InstSeqNum seq_num, ThreadID tid);
31611308Santhony.gutierrez@amd.com
31711308Santhony.gutierrez@amd.com    /** Checks if a thread is stalled. */
31811308Santhony.gutierrez@amd.com    bool checkStall(ThreadID tid) const;
31911308Santhony.gutierrez@amd.com
32011308Santhony.gutierrez@amd.com    /** Updates overall fetch stage status; to be called at the end of each
32111308Santhony.gutierrez@amd.com     * cycle. */
32211308Santhony.gutierrez@amd.com    FetchStatus updateFetchStatus();
32311308Santhony.gutierrez@amd.com
32411308Santhony.gutierrez@amd.com  public:
32511308Santhony.gutierrez@amd.com    /** Squashes a specific thread and resets the PC. Also tells the CPU to
32611308Santhony.gutierrez@amd.com     * remove any instructions that are not in the ROB. The source of this
32711308Santhony.gutierrez@amd.com     * squash should be the commit stage.
32811308Santhony.gutierrez@amd.com     */
32911308Santhony.gutierrez@amd.com    void squash(const TheISA::PCState &newPC, const InstSeqNum seq_num,
33011308Santhony.gutierrez@amd.com                DynInstPtr squashInst, ThreadID tid);
33111308Santhony.gutierrez@amd.com
33211308Santhony.gutierrez@amd.com    /** Ticks the fetch stage, processing all inputs signals and fetching
33311308Santhony.gutierrez@amd.com     * as many instructions as possible.
33411308Santhony.gutierrez@amd.com     */
33511308Santhony.gutierrez@amd.com    void tick();
33611308Santhony.gutierrez@amd.com
33711308Santhony.gutierrez@amd.com    /** Checks all input signals and updates the status as necessary.
33811308Santhony.gutierrez@amd.com     *  @return: Returns if the status has changed due to input signals.
33911308Santhony.gutierrez@amd.com     */
34011308Santhony.gutierrez@amd.com    bool checkSignalsAndUpdate(ThreadID tid);
34111308Santhony.gutierrez@amd.com
34211308Santhony.gutierrez@amd.com    /** Does the actual fetching of instructions and passing them on to the
34311308Santhony.gutierrez@amd.com     * next stage.
34411308Santhony.gutierrez@amd.com     * @param status_change fetch() sets this variable if there was a status
34511308Santhony.gutierrez@amd.com     * change (ie switching to IcacheMissStall).
34611308Santhony.gutierrez@amd.com     */
34711308Santhony.gutierrez@amd.com    void fetch(bool &status_change);
34811308Santhony.gutierrez@amd.com
34911308Santhony.gutierrez@amd.com    /** Align a PC to the start of a fetch buffer block. */
35011308Santhony.gutierrez@amd.com    Addr fetchBufferAlignPC(Addr addr)
35111308Santhony.gutierrez@amd.com    {
35211308Santhony.gutierrez@amd.com        return (addr & ~(fetchBufferMask));
35311308Santhony.gutierrez@amd.com    }
35411308Santhony.gutierrez@amd.com
35511308Santhony.gutierrez@amd.com    /** The decoder. */
35611308Santhony.gutierrez@amd.com    TheISA::Decoder *decoder[Impl::MaxThreads];
35711308Santhony.gutierrez@amd.com
35811308Santhony.gutierrez@amd.com  private:
35911308Santhony.gutierrez@amd.com    DynInstPtr buildInst(ThreadID tid, StaticInstPtr staticInst,
36011308Santhony.gutierrez@amd.com                         StaticInstPtr curMacroop, TheISA::PCState thisPC,
36111308Santhony.gutierrez@amd.com                         TheISA::PCState nextPC, bool trace);
36211308Santhony.gutierrez@amd.com
36311308Santhony.gutierrez@amd.com    /** Returns the appropriate thread to fetch, given the fetch policy. */
36411308Santhony.gutierrez@amd.com    ThreadID getFetchingThread(FetchPriority &fetch_priority);
36511308Santhony.gutierrez@amd.com
36611308Santhony.gutierrez@amd.com    /** Returns the appropriate thread to fetch using a round robin policy. */
36711308Santhony.gutierrez@amd.com    ThreadID roundRobin();
36811308Santhony.gutierrez@amd.com
36911308Santhony.gutierrez@amd.com    /** Returns the appropriate thread to fetch using the IQ count policy. */
37011308Santhony.gutierrez@amd.com    ThreadID iqCount();
37111308Santhony.gutierrez@amd.com
37211308Santhony.gutierrez@amd.com    /** Returns the appropriate thread to fetch using the LSQ count policy. */
37311308Santhony.gutierrez@amd.com    ThreadID lsqCount();
37411308Santhony.gutierrez@amd.com
37511308Santhony.gutierrez@amd.com    /** Returns the appropriate thread to fetch using the branch count
37612065Snikos.nikoleris@arm.com     * policy. */
37711308Santhony.gutierrez@amd.com    ThreadID branchCount();
37811308Santhony.gutierrez@amd.com
37911308Santhony.gutierrez@amd.com    /** Pipeline the next I-cache access to the current one. */
38011308Santhony.gutierrez@amd.com    void pipelineIcacheAccesses(ThreadID tid);
38112065Snikos.nikoleris@arm.com
38212065Snikos.nikoleris@arm.com    /** Profile the reasons of fetch stall. */
38311308Santhony.gutierrez@amd.com    void profileStall(ThreadID tid);
38411308Santhony.gutierrez@amd.com
38511308Santhony.gutierrez@amd.com  private:
38611308Santhony.gutierrez@amd.com    /** Pointer to the O3CPU. */
38711308Santhony.gutierrez@amd.com    O3CPU *cpu;
38811308Santhony.gutierrez@amd.com
38911308Santhony.gutierrez@amd.com    /** Time buffer interface. */
39011308Santhony.gutierrez@amd.com    TimeBuffer<TimeStruct> *timeBuffer;
39111308Santhony.gutierrez@amd.com
39211308Santhony.gutierrez@amd.com    /** Wire to get decode's information from backwards time buffer. */
39311308Santhony.gutierrez@amd.com    typename TimeBuffer<TimeStruct>::wire fromDecode;
39411308Santhony.gutierrez@amd.com
39511308Santhony.gutierrez@amd.com    /** Wire to get rename's information from backwards time buffer. */
39611308Santhony.gutierrez@amd.com    typename TimeBuffer<TimeStruct>::wire fromRename;
39711308Santhony.gutierrez@amd.com
39811308Santhony.gutierrez@amd.com    /** Wire to get iew's information from backwards time buffer. */
39911308Santhony.gutierrez@amd.com    typename TimeBuffer<TimeStruct>::wire fromIEW;
40011308Santhony.gutierrez@amd.com
40111308Santhony.gutierrez@amd.com    /** Wire to get commit's information from backwards time buffer. */
40211308Santhony.gutierrez@amd.com    typename TimeBuffer<TimeStruct>::wire fromCommit;
40311308Santhony.gutierrez@amd.com
40411308Santhony.gutierrez@amd.com    /** Internal fetch instruction queue. */
40511308Santhony.gutierrez@amd.com    TimeBuffer<FetchStruct> *fetchQueue;
40611308Santhony.gutierrez@amd.com
40711308Santhony.gutierrez@amd.com    //Might be annoying how this name is different than the queue.
40811308Santhony.gutierrez@amd.com    /** Wire used to write any information heading to decode. */
40911308Santhony.gutierrez@amd.com    typename TimeBuffer<FetchStruct>::wire toDecode;
41011308Santhony.gutierrez@amd.com
41111308Santhony.gutierrez@amd.com    /** BPredUnit. */
41211308Santhony.gutierrez@amd.com    BPredUnit *branchPred;
41311308Santhony.gutierrez@amd.com
41411308Santhony.gutierrez@amd.com    TheISA::PCState pc[Impl::MaxThreads];
41511308Santhony.gutierrez@amd.com
41611308Santhony.gutierrez@amd.com    Addr fetchOffset[Impl::MaxThreads];
41711308Santhony.gutierrez@amd.com
41811308Santhony.gutierrez@amd.com    StaticInstPtr macroop[Impl::MaxThreads];
41911308Santhony.gutierrez@amd.com
42011308Santhony.gutierrez@amd.com    /** Can the fetch stage redirect from an interrupt on this instruction? */
42111308Santhony.gutierrez@amd.com    bool delayedCommit[Impl::MaxThreads];
42211308Santhony.gutierrez@amd.com
42311308Santhony.gutierrez@amd.com    /** Memory request used to access cache. */
42411308Santhony.gutierrez@amd.com    RequestPtr memReq[Impl::MaxThreads];
42511308Santhony.gutierrez@amd.com
42611308Santhony.gutierrez@amd.com    /** Variable that tracks if fetch has written to the time buffer this
42711308Santhony.gutierrez@amd.com     * cycle. Used to tell CPU if there is activity this cycle.
42811308Santhony.gutierrez@amd.com     */
42911308Santhony.gutierrez@amd.com    bool wroteToTimeBuffer;
43011308Santhony.gutierrez@amd.com
43112598Snikos.nikoleris@arm.com    /** Tracks how many instructions has been fetched this cycle. */
43212598Snikos.nikoleris@arm.com    int numInst;
43311308Santhony.gutierrez@amd.com
43411308Santhony.gutierrez@amd.com    /** Source of possible stalls. */
43511308Santhony.gutierrez@amd.com    struct Stalls {
43611308Santhony.gutierrez@amd.com        bool decode;
43711308Santhony.gutierrez@amd.com        bool rename;
43811308Santhony.gutierrez@amd.com        bool iew;
43911308Santhony.gutierrez@amd.com        bool commit;
44011308Santhony.gutierrez@amd.com        bool drain;
44111308Santhony.gutierrez@amd.com    };
44211308Santhony.gutierrez@amd.com
44311308Santhony.gutierrez@amd.com    /** Tracks which stages are telling fetch to stall. */
44411308Santhony.gutierrez@amd.com    Stalls stalls[Impl::MaxThreads];
44511308Santhony.gutierrez@amd.com
44611308Santhony.gutierrez@amd.com    /** Decode to fetch delay. */
44711308Santhony.gutierrez@amd.com    Cycles decodeToFetchDelay;
44811308Santhony.gutierrez@amd.com
44911308Santhony.gutierrez@amd.com    /** Rename to fetch delay. */
45011308Santhony.gutierrez@amd.com    Cycles renameToFetchDelay;
45111308Santhony.gutierrez@amd.com
45211308Santhony.gutierrez@amd.com    /** IEW to fetch delay. */
45311308Santhony.gutierrez@amd.com    Cycles iewToFetchDelay;
45411308Santhony.gutierrez@amd.com
45511308Santhony.gutierrez@amd.com    /** Commit to fetch delay. */
45611308Santhony.gutierrez@amd.com    Cycles commitToFetchDelay;
45711308Santhony.gutierrez@amd.com
45811308Santhony.gutierrez@amd.com    /** The width of fetch in instructions. */
45911308Santhony.gutierrez@amd.com    unsigned fetchWidth;
46011308Santhony.gutierrez@amd.com
46111308Santhony.gutierrez@amd.com    /** Is the cache blocked?  If so no threads can access it. */
46212065Snikos.nikoleris@arm.com    bool cacheBlocked;
46312065Snikos.nikoleris@arm.com
46412065Snikos.nikoleris@arm.com    /** The packet that is waiting to be retried. */
46512065Snikos.nikoleris@arm.com    PacketPtr retryPkt;
46612065Snikos.nikoleris@arm.com
46712065Snikos.nikoleris@arm.com    /** The thread that is waiting on the cache to tell fetch to retry. */
46812065Snikos.nikoleris@arm.com    ThreadID retryTid;
46912065Snikos.nikoleris@arm.com
47012065Snikos.nikoleris@arm.com    /** Cache block size. */
47112065Snikos.nikoleris@arm.com    unsigned int cacheBlkSize;
47212065Snikos.nikoleris@arm.com
47313731Sandreas.sandberg@arm.com    /** The size of the fetch buffer in bytes. The fetch buffer
47412065Snikos.nikoleris@arm.com     *  itself may be smaller than a cache line.
47512065Snikos.nikoleris@arm.com     */
47612065Snikos.nikoleris@arm.com    unsigned fetchBufferSize;
47712065Snikos.nikoleris@arm.com
47812065Snikos.nikoleris@arm.com    /** Mask to align a fetch address to a fetch buffer boundary. */
47912065Snikos.nikoleris@arm.com    Addr fetchBufferMask;
48012065Snikos.nikoleris@arm.com
48111308Santhony.gutierrez@amd.com    /** The fetch data that is being fetched and buffered. */
48211308Santhony.gutierrez@amd.com    uint8_t *fetchBuffer[Impl::MaxThreads];
48312065Snikos.nikoleris@arm.com
48411308Santhony.gutierrez@amd.com    /** The PC of the first instruction loaded into the fetch buffer. */
48511308Santhony.gutierrez@amd.com    Addr fetchBufferPC[Impl::MaxThreads];
48611308Santhony.gutierrez@amd.com
48711308Santhony.gutierrez@amd.com    /** Whether or not the fetch buffer data is valid. */
48811308Santhony.gutierrez@amd.com    bool fetchBufferValid[Impl::MaxThreads];
48911308Santhony.gutierrez@amd.com
49011308Santhony.gutierrez@amd.com    /** Size of instructions. */
49111308Santhony.gutierrez@amd.com    int instSize;
49211308Santhony.gutierrez@amd.com
49311308Santhony.gutierrez@amd.com    /** Icache stall statistics. */
49411308Santhony.gutierrez@amd.com    Counter lastIcacheStall[Impl::MaxThreads];
49511308Santhony.gutierrez@amd.com
49611308Santhony.gutierrez@amd.com    /** List of Active Threads */
49711308Santhony.gutierrez@amd.com    std::list<ThreadID> *activeThreads;
49811308Santhony.gutierrez@amd.com
49911308Santhony.gutierrez@amd.com    /** Number of threads. */
50011308Santhony.gutierrez@amd.com    ThreadID numThreads;
50111308Santhony.gutierrez@amd.com
50211308Santhony.gutierrez@amd.com    /** Number of threads that are actively fetching. */
50311308Santhony.gutierrez@amd.com    ThreadID numFetchingThreads;
50411308Santhony.gutierrez@amd.com
50511308Santhony.gutierrez@amd.com    /** Thread ID being fetched. */
50611308Santhony.gutierrez@amd.com    ThreadID threadFetched;
50711308Santhony.gutierrez@amd.com
50811308Santhony.gutierrez@amd.com    /** Checks if there is an interrupt pending.  If there is, fetch
50911308Santhony.gutierrez@amd.com     * must stop once it is not fetching PAL instructions.
51011308Santhony.gutierrez@amd.com     */
51111308Santhony.gutierrez@amd.com    bool interruptPending;
51211308Santhony.gutierrez@amd.com
51311308Santhony.gutierrez@amd.com    /** Set to true if a pipelined I-cache request should be issued. */
51413731Sandreas.sandberg@arm.com    bool issuePipelinedIfetch[Impl::MaxThreads];
51511308Santhony.gutierrez@amd.com
51611308Santhony.gutierrez@amd.com    /** Event used to delay fault generation of translation faults */
51711308Santhony.gutierrez@amd.com    FinishTranslationEvent finishTranslationEvent;
51811308Santhony.gutierrez@amd.com
51911308Santhony.gutierrez@amd.com    // @todo: Consider making these vectors and tracking on a per thread basis.
52011308Santhony.gutierrez@amd.com    /** Stat for total number of cycles stalled due to an icache miss. */
52111308Santhony.gutierrez@amd.com    Stats::Scalar icacheStallCycles;
52211308Santhony.gutierrez@amd.com    /** Stat for total number of fetched instructions. */
52311308Santhony.gutierrez@amd.com    Stats::Scalar fetchedInsts;
52411308Santhony.gutierrez@amd.com    /** Total number of fetched branches. */
52511308Santhony.gutierrez@amd.com    Stats::Scalar fetchedBranches;
52611308Santhony.gutierrez@amd.com    /** Stat for total number of predicted branches. */
52711308Santhony.gutierrez@amd.com    Stats::Scalar predictedBranches;
52811308Santhony.gutierrez@amd.com    /** Stat for total number of cycles spent fetching. */
52911308Santhony.gutierrez@amd.com    Stats::Scalar fetchCycles;
53011308Santhony.gutierrez@amd.com    /** Stat for total number of cycles spent squashing. */
53111308Santhony.gutierrez@amd.com    Stats::Scalar fetchSquashCycles;
53211308Santhony.gutierrez@amd.com    /** Stat for total number of cycles spent waiting for translation */
53311308Santhony.gutierrez@amd.com    Stats::Scalar fetchTlbCycles;
53411308Santhony.gutierrez@amd.com    /** Stat for total number of cycles spent blocked due to other stages in
53511308Santhony.gutierrez@amd.com     * the pipeline.
53611308Santhony.gutierrez@amd.com     */
53711308Santhony.gutierrez@amd.com    Stats::Scalar fetchIdleCycles;
53811308Santhony.gutierrez@amd.com    /** Total number of cycles spent blocked. */
53911308Santhony.gutierrez@amd.com    Stats::Scalar fetchBlockedCycles;
54011308Santhony.gutierrez@amd.com    /** Total number of cycles spent in any other state. */
54111308Santhony.gutierrez@amd.com    Stats::Scalar fetchMiscStallCycles;
54211308Santhony.gutierrez@amd.com    /** Total number of cycles spent in waiting for drains. */
54311308Santhony.gutierrez@amd.com    Stats::Scalar fetchPendingDrainCycles;
54411308Santhony.gutierrez@amd.com    /** Total number of stall cycles caused by no active threads to run. */
54511308Santhony.gutierrez@amd.com    Stats::Scalar fetchNoActiveThreadStallCycles;
54611308Santhony.gutierrez@amd.com    /** Total number of stall cycles caused by pending traps. */
54711308Santhony.gutierrez@amd.com    Stats::Scalar fetchPendingTrapStallCycles;
54813731Sandreas.sandberg@arm.com    /** Total number of stall cycles caused by pending quiesce instructions. */
54911308Santhony.gutierrez@amd.com    Stats::Scalar fetchPendingQuiesceStallCycles;
55011308Santhony.gutierrez@amd.com    /** Total number of stall cycles caused by I-cache wait retrys. */
55111308Santhony.gutierrez@amd.com    Stats::Scalar fetchIcacheWaitRetryStallCycles;
55211308Santhony.gutierrez@amd.com    /** Stat for total number of fetched cache lines. */
55311308Santhony.gutierrez@amd.com    Stats::Scalar fetchedCacheLines;
55411308Santhony.gutierrez@amd.com    /** Total number of outstanding icache accesses that were dropped
55511308Santhony.gutierrez@amd.com     * due to a squash.
55611308Santhony.gutierrez@amd.com     */
55711308Santhony.gutierrez@amd.com    Stats::Scalar fetchIcacheSquashes;
55811308Santhony.gutierrez@amd.com    /** Total number of outstanding tlb accesses that were dropped
55911308Santhony.gutierrez@amd.com     * due to a squash.
56011308Santhony.gutierrez@amd.com     */
56111308Santhony.gutierrez@amd.com    Stats::Scalar fetchTlbSquashes;
56211308Santhony.gutierrez@amd.com    /** Distribution of number of instructions fetched each cycle. */
56311308Santhony.gutierrez@amd.com    Stats::Distribution fetchNisnDist;
56411308Santhony.gutierrez@amd.com    /** Rate of how often fetch was idle. */
56511308Santhony.gutierrez@amd.com    Stats::Formula idleRate;
56611308Santhony.gutierrez@amd.com    /** Number of branch fetches per cycle. */
56711308Santhony.gutierrez@amd.com    Stats::Formula branchRate;
56811308Santhony.gutierrez@amd.com    /** Number of instruction fetched per cycle. */
56911308Santhony.gutierrez@amd.com    Stats::Formula fetchRate;
57011308Santhony.gutierrez@amd.com};
57111308Santhony.gutierrez@amd.com
57211308Santhony.gutierrez@amd.com#endif //__CPU_O3_FETCH_HH__
57311308Santhony.gutierrez@amd.com