fetch.hh revision 8460:3893d9d2c6c2
111012Sandreas.sandberg@arm.com/*
211897Ssudhanshu.jha@arm.com * Copyright (c) 2010 ARM Limited
311012Sandreas.sandberg@arm.com * All rights reserved
411012Sandreas.sandberg@arm.com *
511012Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
611012Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
711012Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
811012Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
911012Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1011012Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1111012Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1211012Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1311012Sandreas.sandberg@arm.com *
1411012Sandreas.sandberg@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
1511012Sandreas.sandberg@arm.com * All rights reserved.
1611012Sandreas.sandberg@arm.com *
1711012Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1811012Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1911012Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
2011012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
2111012Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
2211012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2311012Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2411012Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2511012Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2611012Sandreas.sandberg@arm.com * this software without specific prior written permission.
2711012Sandreas.sandberg@arm.com *
2811012Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2911012Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3011012Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3111012Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3211012Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3311012Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3411012Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3511012Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3611012Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3711012Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3811012Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3911012Sandreas.sandberg@arm.com *
4011012Sandreas.sandberg@arm.com * Authors: Kevin Lim
4111012Sandreas.sandberg@arm.com *          Korey Sewell
4211012Sandreas.sandberg@arm.com */
4311012Sandreas.sandberg@arm.com
4411012Sandreas.sandberg@arm.com#ifndef __CPU_O3_FETCH_HH__
4511012Sandreas.sandberg@arm.com#define __CPU_O3_FETCH_HH__
4611012Sandreas.sandberg@arm.com
4711012Sandreas.sandberg@arm.com#include "arch/predecoder.hh"
4811012Sandreas.sandberg@arm.com#include "arch/utility.hh"
4911012Sandreas.sandberg@arm.com#include "base/statistics.hh"
5011012Sandreas.sandberg@arm.com#include "config/the_isa.hh"
5111012Sandreas.sandberg@arm.com#include "cpu/pc_event.hh"
5211012Sandreas.sandberg@arm.com#include "cpu/timebuf.hh"
5311012Sandreas.sandberg@arm.com#include "cpu/translation.hh"
5411012Sandreas.sandberg@arm.com#include "mem/packet.hh"
5511012Sandreas.sandberg@arm.com#include "mem/port.hh"
5611012Sandreas.sandberg@arm.com#include "sim/eventq.hh"
5711012Sandreas.sandberg@arm.com
5811012Sandreas.sandberg@arm.comclass DerivO3CPUParams;
5911012Sandreas.sandberg@arm.com
6011012Sandreas.sandberg@arm.com/**
6111012Sandreas.sandberg@arm.com * DefaultFetch class handles both single threaded and SMT fetch. Its
6211012Sandreas.sandberg@arm.com * width is specified by the parameters; each cycle it tries to fetch
6311012Sandreas.sandberg@arm.com * that many instructions. It supports using a branch predictor to
6411012Sandreas.sandberg@arm.com * predict direction and targets.
6511012Sandreas.sandberg@arm.com * It supports the idling functionality of the CPU by indicating to
6611012Sandreas.sandberg@arm.com * the CPU when it is active and inactive.
6711012Sandreas.sandberg@arm.com */
6811012Sandreas.sandberg@arm.comtemplate <class Impl>
6911012Sandreas.sandberg@arm.comclass DefaultFetch
7011012Sandreas.sandberg@arm.com{
7111012Sandreas.sandberg@arm.com  public:
7211012Sandreas.sandberg@arm.com    /** Typedefs from Impl. */
7311012Sandreas.sandberg@arm.com    typedef typename Impl::CPUPol CPUPol;
7411012Sandreas.sandberg@arm.com    typedef typename Impl::DynInst DynInst;
7511012Sandreas.sandberg@arm.com    typedef typename Impl::DynInstPtr DynInstPtr;
7611012Sandreas.sandberg@arm.com    typedef typename Impl::O3CPU O3CPU;
7711012Sandreas.sandberg@arm.com
7811012Sandreas.sandberg@arm.com    /** Typedefs from the CPU policy. */
7911012Sandreas.sandberg@arm.com    typedef typename CPUPol::BPredUnit BPredUnit;
8011012Sandreas.sandberg@arm.com    typedef typename CPUPol::FetchStruct FetchStruct;
8111012Sandreas.sandberg@arm.com    typedef typename CPUPol::TimeStruct TimeStruct;
8211012Sandreas.sandberg@arm.com
8311012Sandreas.sandberg@arm.com    /** Typedefs from ISA. */
8411012Sandreas.sandberg@arm.com    typedef TheISA::MachInst MachInst;
8511012Sandreas.sandberg@arm.com    typedef TheISA::ExtMachInst ExtMachInst;
8611012Sandreas.sandberg@arm.com
8711012Sandreas.sandberg@arm.com    /** IcachePort class for DefaultFetch.  Handles doing the
8811012Sandreas.sandberg@arm.com     * communication with the cache/memory.
8911012Sandreas.sandberg@arm.com     */
9011012Sandreas.sandberg@arm.com    class IcachePort : public Port
9111012Sandreas.sandberg@arm.com    {
9211012Sandreas.sandberg@arm.com      protected:
9311012Sandreas.sandberg@arm.com        /** Pointer to fetch. */
9411012Sandreas.sandberg@arm.com        DefaultFetch<Impl> *fetch;
9511012Sandreas.sandberg@arm.com
9611012Sandreas.sandberg@arm.com      public:
9711012Sandreas.sandberg@arm.com        /** Default constructor. */
9811012Sandreas.sandberg@arm.com        IcachePort(DefaultFetch<Impl> *_fetch)
9911012Sandreas.sandberg@arm.com            : Port(_fetch->name() + "-iport", _fetch->cpu), fetch(_fetch)
10011012Sandreas.sandberg@arm.com        { }
10111012Sandreas.sandberg@arm.com
10211012Sandreas.sandberg@arm.com        bool snoopRangeSent;
10311012Sandreas.sandberg@arm.com
10411012Sandreas.sandberg@arm.com        virtual void setPeer(Port *port);
10511012Sandreas.sandberg@arm.com
10611012Sandreas.sandberg@arm.com      protected:
10711012Sandreas.sandberg@arm.com        /** Atomic version of receive.  Panics. */
10811012Sandreas.sandberg@arm.com        virtual Tick recvAtomic(PacketPtr pkt);
10911012Sandreas.sandberg@arm.com
11011012Sandreas.sandberg@arm.com        /** Functional version of receive.  Panics. */
11111012Sandreas.sandberg@arm.com        virtual void recvFunctional(PacketPtr pkt);
11211012Sandreas.sandberg@arm.com
11311012Sandreas.sandberg@arm.com        /** Receives status change.  Other than range changing, panics. */
11411012Sandreas.sandberg@arm.com        virtual void recvStatusChange(Status status);
11511012Sandreas.sandberg@arm.com
11611012Sandreas.sandberg@arm.com        /** Returns the address ranges of this device. */
11711012Sandreas.sandberg@arm.com        virtual void getDeviceAddressRanges(AddrRangeList &resp,
11811012Sandreas.sandberg@arm.com                                            bool &snoop)
11911012Sandreas.sandberg@arm.com        { resp.clear(); snoop = true; }
12011012Sandreas.sandberg@arm.com
12111012Sandreas.sandberg@arm.com        /** Timing version of receive.  Handles setting fetch to the
12211012Sandreas.sandberg@arm.com         * proper status to start fetching. */
12311012Sandreas.sandberg@arm.com        virtual bool recvTiming(PacketPtr pkt);
12411012Sandreas.sandberg@arm.com
12511012Sandreas.sandberg@arm.com        /** Handles doing a retry of a failed fetch. */
12611012Sandreas.sandberg@arm.com        virtual void recvRetry();
12711012Sandreas.sandberg@arm.com    };
12811012Sandreas.sandberg@arm.com
12911012Sandreas.sandberg@arm.com    class FetchTranslation : public BaseTLB::Translation
13011012Sandreas.sandberg@arm.com    {
13111012Sandreas.sandberg@arm.com      protected:
13211012Sandreas.sandberg@arm.com        DefaultFetch<Impl> *fetch;
13311012Sandreas.sandberg@arm.com
13411012Sandreas.sandberg@arm.com      public:
13511012Sandreas.sandberg@arm.com        FetchTranslation(DefaultFetch<Impl> *_fetch)
13611012Sandreas.sandberg@arm.com            : fetch(_fetch)
13711012Sandreas.sandberg@arm.com        {}
13811012Sandreas.sandberg@arm.com
13911897Ssudhanshu.jha@arm.com        void
14011897Ssudhanshu.jha@arm.com        markDelayed()
14111897Ssudhanshu.jha@arm.com        {}
14211897Ssudhanshu.jha@arm.com
14311012Sandreas.sandberg@arm.com        void
14411012Sandreas.sandberg@arm.com        finish(Fault fault, RequestPtr req, ThreadContext *tc,
14511012Sandreas.sandberg@arm.com               BaseTLB::Mode mode)
14611012Sandreas.sandberg@arm.com        {
14711012Sandreas.sandberg@arm.com            assert(mode == BaseTLB::Execute);
14811012Sandreas.sandberg@arm.com            fetch->finishTranslation(fault, req);
14911012Sandreas.sandberg@arm.com            delete this;
15011012Sandreas.sandberg@arm.com        }
15111012Sandreas.sandberg@arm.com    };
15211012Sandreas.sandberg@arm.com
15311897Ssudhanshu.jha@arm.com  public:
15411897Ssudhanshu.jha@arm.com    /** Overall fetch status. Used to determine if the CPU can
15511897Ssudhanshu.jha@arm.com     * deschedule itsef due to a lack of activity.
15611897Ssudhanshu.jha@arm.com     */
15711897Ssudhanshu.jha@arm.com    enum FetchStatus {
15811012Sandreas.sandberg@arm.com        Active,
15911012Sandreas.sandberg@arm.com        Inactive
16011012Sandreas.sandberg@arm.com    };
16111897Ssudhanshu.jha@arm.com
16211012Sandreas.sandberg@arm.com    /** Individual thread status. */
16311012Sandreas.sandberg@arm.com    enum ThreadStatus {
16411012Sandreas.sandberg@arm.com        Running,
16511012Sandreas.sandberg@arm.com        Idle,
16611012Sandreas.sandberg@arm.com        Squashing,
16711012Sandreas.sandberg@arm.com        Blocked,
16811012Sandreas.sandberg@arm.com        Fetching,
16911012Sandreas.sandberg@arm.com        TrapPending,
17011012Sandreas.sandberg@arm.com        QuiescePending,
17111012Sandreas.sandberg@arm.com        SwitchOut,
17211012Sandreas.sandberg@arm.com        ItlbWait,
17311012Sandreas.sandberg@arm.com        IcacheWaitResponse,
17411012Sandreas.sandberg@arm.com        IcacheWaitRetry,
17511012Sandreas.sandberg@arm.com        IcacheAccessComplete,
17611012Sandreas.sandberg@arm.com        NoGoodAddr
17711012Sandreas.sandberg@arm.com    };
17811012Sandreas.sandberg@arm.com
17911012Sandreas.sandberg@arm.com    /** Fetching Policy, Add new policies here.*/
18011012Sandreas.sandberg@arm.com    enum FetchPriority {
18111012Sandreas.sandberg@arm.com        SingleThread,
18211012Sandreas.sandberg@arm.com        RoundRobin,
18311012Sandreas.sandberg@arm.com        Branch,
18411012Sandreas.sandberg@arm.com        IQ,
18511012Sandreas.sandberg@arm.com        LSQ
18611012Sandreas.sandberg@arm.com    };
18711012Sandreas.sandberg@arm.com
18811012Sandreas.sandberg@arm.com  private:
18911012Sandreas.sandberg@arm.com    /** Fetch status. */
19011012Sandreas.sandberg@arm.com    FetchStatus _status;
19111012Sandreas.sandberg@arm.com
19211012Sandreas.sandberg@arm.com    /** Per-thread status. */
19311012Sandreas.sandberg@arm.com    ThreadStatus fetchStatus[Impl::MaxThreads];
19411012Sandreas.sandberg@arm.com
19511012Sandreas.sandberg@arm.com    /** Fetch policy. */
19611012Sandreas.sandberg@arm.com    FetchPriority fetchPolicy;
19711012Sandreas.sandberg@arm.com
19811012Sandreas.sandberg@arm.com    /** List that has the threads organized by priority. */
19911012Sandreas.sandberg@arm.com    std::list<ThreadID> priorityList;
20011012Sandreas.sandberg@arm.com
20111012Sandreas.sandberg@arm.com  public:
20211012Sandreas.sandberg@arm.com    /** DefaultFetch constructor. */
20311012Sandreas.sandberg@arm.com    DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params);
20411012Sandreas.sandberg@arm.com
20511012Sandreas.sandberg@arm.com    /** Returns the name of fetch. */
20611012Sandreas.sandberg@arm.com    std::string name() const;
20711012Sandreas.sandberg@arm.com
20811012Sandreas.sandberg@arm.com    /** Registers statistics. */
20911012Sandreas.sandberg@arm.com    void regStats();
21011012Sandreas.sandberg@arm.com
21111012Sandreas.sandberg@arm.com    /** Returns the icache port. */
21211012Sandreas.sandberg@arm.com    Port *getIcachePort() { return icachePort; }
21311012Sandreas.sandberg@arm.com
21411012Sandreas.sandberg@arm.com    /** Sets the main backwards communication time buffer pointer. */
21511012Sandreas.sandberg@arm.com    void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
21611012Sandreas.sandberg@arm.com
21711012Sandreas.sandberg@arm.com    /** Sets pointer to list of active threads. */
21811012Sandreas.sandberg@arm.com    void setActiveThreads(std::list<ThreadID> *at_ptr);
21911012Sandreas.sandberg@arm.com
22011012Sandreas.sandberg@arm.com    /** Sets pointer to time buffer used to communicate to the next stage. */
22111012Sandreas.sandberg@arm.com    void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
22211012Sandreas.sandberg@arm.com
22311012Sandreas.sandberg@arm.com    /** Initialize stage. */
22411012Sandreas.sandberg@arm.com    void initStage();
22511012Sandreas.sandberg@arm.com
22611012Sandreas.sandberg@arm.com    /** Tells the fetch stage that the Icache is set. */
22711012Sandreas.sandberg@arm.com    void setIcache();
22811012Sandreas.sandberg@arm.com
22911012Sandreas.sandberg@arm.com    /** Processes cache completion event. */
23011012Sandreas.sandberg@arm.com    void processCacheCompletion(PacketPtr pkt);
23111012Sandreas.sandberg@arm.com
23211012Sandreas.sandberg@arm.com    /** Begins the drain of the fetch stage. */
23311012Sandreas.sandberg@arm.com    bool drain();
23411012Sandreas.sandberg@arm.com
23511012Sandreas.sandberg@arm.com    /** Resumes execution after a drain. */
23611012Sandreas.sandberg@arm.com    void resume();
23711012Sandreas.sandberg@arm.com
23811012Sandreas.sandberg@arm.com    /** Tells fetch stage to prepare to be switched out. */
23911012Sandreas.sandberg@arm.com    void switchOut();
24011012Sandreas.sandberg@arm.com
24111012Sandreas.sandberg@arm.com    /** Takes over from another CPU's thread. */
24211012Sandreas.sandberg@arm.com    void takeOverFrom();
24311012Sandreas.sandberg@arm.com
24411012Sandreas.sandberg@arm.com    /** Checks if the fetch stage is switched out. */
24511012Sandreas.sandberg@arm.com    bool isSwitchedOut() { return switchedOut; }
24611012Sandreas.sandberg@arm.com
24711012Sandreas.sandberg@arm.com    /** Tells fetch to wake up from a quiesce instruction. */
24811012Sandreas.sandberg@arm.com    void wakeFromQuiesce();
24911012Sandreas.sandberg@arm.com
25011012Sandreas.sandberg@arm.com  private:
25111897Ssudhanshu.jha@arm.com    /** Changes the status of this stage to active, and indicates this
25211897Ssudhanshu.jha@arm.com     * to the CPU.
25311897Ssudhanshu.jha@arm.com     */
25411897Ssudhanshu.jha@arm.com    inline void switchToActive();
25511897Ssudhanshu.jha@arm.com
25611897Ssudhanshu.jha@arm.com    /** Changes the status of this stage to inactive, and indicates
25711897Ssudhanshu.jha@arm.com     * this to the CPU.
25811897Ssudhanshu.jha@arm.com     */
25911897Ssudhanshu.jha@arm.com    inline void switchToInactive();
26011897Ssudhanshu.jha@arm.com
26111897Ssudhanshu.jha@arm.com    /**
26211897Ssudhanshu.jha@arm.com     * Looks up in the branch predictor to see if the next PC should be
26311897Ssudhanshu.jha@arm.com     * either next PC+=MachInst or a branch target.
26411897Ssudhanshu.jha@arm.com     * @param next_PC Next PC variable passed in by reference.  It is
26511897Ssudhanshu.jha@arm.com     * expected to be set to the current PC; it will be updated with what
26611897Ssudhanshu.jha@arm.com     * the next PC will be.
26711897Ssudhanshu.jha@arm.com     * @param next_NPC Used for ISAs which use delay slots.
26811897Ssudhanshu.jha@arm.com     * @return Whether or not a branch was predicted as taken.
26911897Ssudhanshu.jha@arm.com     */
27011897Ssudhanshu.jha@arm.com    bool lookupAndUpdateNextPC(DynInstPtr &inst, TheISA::PCState &pc);
27111897Ssudhanshu.jha@arm.com
27211897Ssudhanshu.jha@arm.com    /**
27311897Ssudhanshu.jha@arm.com     * Fetches the cache line that contains fetch_PC.  Returns any
27411897Ssudhanshu.jha@arm.com     * fault that happened.  Puts the data into the class variable
27511897Ssudhanshu.jha@arm.com     * cacheData.
27611897Ssudhanshu.jha@arm.com     * @param vaddr The memory address that is being fetched from.
27711897Ssudhanshu.jha@arm.com     * @param ret_fault The fault reference that will be set to the result of
27811897Ssudhanshu.jha@arm.com     * the icache access.
27911897Ssudhanshu.jha@arm.com     * @param tid Thread id.
28011897Ssudhanshu.jha@arm.com     * @param pc The actual PC of the current instruction.
28111897Ssudhanshu.jha@arm.com     * @return Any fault that occured.
28211897Ssudhanshu.jha@arm.com     */
28311897Ssudhanshu.jha@arm.com    bool fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc);
28411897Ssudhanshu.jha@arm.com    void finishTranslation(Fault fault, RequestPtr mem_req);
28511897Ssudhanshu.jha@arm.com
28611897Ssudhanshu.jha@arm.com
28711897Ssudhanshu.jha@arm.com    /** Check if an interrupt is pending and that we need to handle
28811897Ssudhanshu.jha@arm.com     */
28911897Ssudhanshu.jha@arm.com    bool
29011897Ssudhanshu.jha@arm.com    checkInterrupt(Addr pc)
29111897Ssudhanshu.jha@arm.com    {
29211897Ssudhanshu.jha@arm.com        return (interruptPending && (THE_ISA != ALPHA_ISA || !(pc & 0x3)));
29311897Ssudhanshu.jha@arm.com    }
29411897Ssudhanshu.jha@arm.com
29511897Ssudhanshu.jha@arm.com    /** Squashes a specific thread and resets the PC. */
29611897Ssudhanshu.jha@arm.com    inline void doSquash(const TheISA::PCState &newPC, ThreadID tid);
29711897Ssudhanshu.jha@arm.com
29811897Ssudhanshu.jha@arm.com    /** Squashes a specific thread and resets the PC. Also tells the CPU to
29911012Sandreas.sandberg@arm.com     * remove any instructions between fetch and decode that should be sqaushed.
30011012Sandreas.sandberg@arm.com     */
30111012Sandreas.sandberg@arm.com    void squashFromDecode(const TheISA::PCState &newPC,
30211012Sandreas.sandberg@arm.com                          const InstSeqNum &seq_num, ThreadID tid);
30311012Sandreas.sandberg@arm.com
30411012Sandreas.sandberg@arm.com    /** Checks if a thread is stalled. */
30511012Sandreas.sandberg@arm.com    bool checkStall(ThreadID tid) const;
30611012Sandreas.sandberg@arm.com
30711012Sandreas.sandberg@arm.com    /** Updates overall fetch stage status; to be called at the end of each
30811012Sandreas.sandberg@arm.com     * cycle. */
30911012Sandreas.sandberg@arm.com    FetchStatus updateFetchStatus();
31011012Sandreas.sandberg@arm.com
31111012Sandreas.sandberg@arm.com  public:
31211012Sandreas.sandberg@arm.com    /** Squashes a specific thread and resets the PC. Also tells the CPU to
31311012Sandreas.sandberg@arm.com     * remove any instructions that are not in the ROB. The source of this
31411012Sandreas.sandberg@arm.com     * squash should be the commit stage.
31511012Sandreas.sandberg@arm.com     */
31611012Sandreas.sandberg@arm.com    void squash(const TheISA::PCState &newPC, const InstSeqNum &seq_num,
31711012Sandreas.sandberg@arm.com                DynInstPtr &squashInst, ThreadID tid);
31811012Sandreas.sandberg@arm.com
31911012Sandreas.sandberg@arm.com    /** Ticks the fetch stage, processing all inputs signals and fetching
32011012Sandreas.sandberg@arm.com     * as many instructions as possible.
32111012Sandreas.sandberg@arm.com     */
32211012Sandreas.sandberg@arm.com    void tick();
32311012Sandreas.sandberg@arm.com
32411012Sandreas.sandberg@arm.com    /** Checks all input signals and updates the status as necessary.
32511012Sandreas.sandberg@arm.com     *  @return: Returns if the status has changed due to input signals.
32611012Sandreas.sandberg@arm.com     */
32711012Sandreas.sandberg@arm.com    bool checkSignalsAndUpdate(ThreadID tid);
32811012Sandreas.sandberg@arm.com
32911012Sandreas.sandberg@arm.com    /** Does the actual fetching of instructions and passing them on to the
33011012Sandreas.sandberg@arm.com     * next stage.
33111012Sandreas.sandberg@arm.com     * @param status_change fetch() sets this variable if there was a status
33211012Sandreas.sandberg@arm.com     * change (ie switching to IcacheMissStall).
33311012Sandreas.sandberg@arm.com     */
33411012Sandreas.sandberg@arm.com    void fetch(bool &status_change);
33511012Sandreas.sandberg@arm.com
33611012Sandreas.sandberg@arm.com    /** Align a PC to the start of an I-cache block. */
33711012Sandreas.sandberg@arm.com    Addr icacheBlockAlignPC(Addr addr)
33811012Sandreas.sandberg@arm.com    {
33911012Sandreas.sandberg@arm.com        return (addr & ~(cacheBlkMask));
34011012Sandreas.sandberg@arm.com    }
34111012Sandreas.sandberg@arm.com
34211012Sandreas.sandberg@arm.com  private:
34311012Sandreas.sandberg@arm.com    DynInstPtr buildInst(ThreadID tid, StaticInstPtr staticInst,
34411012Sandreas.sandberg@arm.com                         StaticInstPtr curMacroop, TheISA::PCState thisPC,
34511012Sandreas.sandberg@arm.com                         TheISA::PCState nextPC, bool trace);
34611012Sandreas.sandberg@arm.com
34711012Sandreas.sandberg@arm.com    /** Handles retrying the fetch access. */
34811012Sandreas.sandberg@arm.com    void recvRetry();
34911012Sandreas.sandberg@arm.com
35011012Sandreas.sandberg@arm.com    /** Returns the appropriate thread to fetch, given the fetch policy. */
35111012Sandreas.sandberg@arm.com    ThreadID getFetchingThread(FetchPriority &fetch_priority);
35211012Sandreas.sandberg@arm.com
35311012Sandreas.sandberg@arm.com    /** Returns the appropriate thread to fetch using a round robin policy. */
35411012Sandreas.sandberg@arm.com    ThreadID roundRobin();
35511012Sandreas.sandberg@arm.com
35611012Sandreas.sandberg@arm.com    /** Returns the appropriate thread to fetch using the IQ count policy. */
35711012Sandreas.sandberg@arm.com    ThreadID iqCount();
35811012Sandreas.sandberg@arm.com
35911012Sandreas.sandberg@arm.com    /** Returns the appropriate thread to fetch using the LSQ count policy. */
36011012Sandreas.sandberg@arm.com    ThreadID lsqCount();
36111012Sandreas.sandberg@arm.com
362    /** Returns the appropriate thread to fetch using the branch count
363     * policy. */
364    ThreadID branchCount();
365
366  private:
367    /** Pointer to the O3CPU. */
368    O3CPU *cpu;
369
370    /** Time buffer interface. */
371    TimeBuffer<TimeStruct> *timeBuffer;
372
373    /** Wire to get decode's information from backwards time buffer. */
374    typename TimeBuffer<TimeStruct>::wire fromDecode;
375
376    /** Wire to get rename's information from backwards time buffer. */
377    typename TimeBuffer<TimeStruct>::wire fromRename;
378
379    /** Wire to get iew's information from backwards time buffer. */
380    typename TimeBuffer<TimeStruct>::wire fromIEW;
381
382    /** Wire to get commit's information from backwards time buffer. */
383    typename TimeBuffer<TimeStruct>::wire fromCommit;
384
385    /** Internal fetch instruction queue. */
386    TimeBuffer<FetchStruct> *fetchQueue;
387
388    //Might be annoying how this name is different than the queue.
389    /** Wire used to write any information heading to decode. */
390    typename TimeBuffer<FetchStruct>::wire toDecode;
391
392    /** Icache interface. */
393    IcachePort *icachePort;
394
395    /** BPredUnit. */
396    BPredUnit branchPred;
397
398    /** Predecoder. */
399    TheISA::Predecoder predecoder;
400
401    TheISA::PCState pc[Impl::MaxThreads];
402
403    Addr fetchOffset[Impl::MaxThreads];
404
405    StaticInstPtr macroop[Impl::MaxThreads];
406
407    /** Can the fetch stage redirect from an interrupt on this instruction? */
408    bool delayedCommit[Impl::MaxThreads];
409
410    /** Memory request used to access cache. */
411    RequestPtr memReq[Impl::MaxThreads];
412
413    /** Variable that tracks if fetch has written to the time buffer this
414     * cycle. Used to tell CPU if there is activity this cycle.
415     */
416    bool wroteToTimeBuffer;
417
418    /** Tracks how many instructions has been fetched this cycle. */
419    int numInst;
420
421    /** Source of possible stalls. */
422    struct Stalls {
423        bool decode;
424        bool rename;
425        bool iew;
426        bool commit;
427    };
428
429    /** Tracks which stages are telling fetch to stall. */
430    Stalls stalls[Impl::MaxThreads];
431
432    /** Decode to fetch delay, in ticks. */
433    unsigned decodeToFetchDelay;
434
435    /** Rename to fetch delay, in ticks. */
436    unsigned renameToFetchDelay;
437
438    /** IEW to fetch delay, in ticks. */
439    unsigned iewToFetchDelay;
440
441    /** Commit to fetch delay, in ticks. */
442    unsigned commitToFetchDelay;
443
444    /** The width of fetch in instructions. */
445    unsigned fetchWidth;
446
447    /** Is the cache blocked?  If so no threads can access it. */
448    bool cacheBlocked;
449
450    /** The packet that is waiting to be retried. */
451    PacketPtr retryPkt;
452
453    /** The thread that is waiting on the cache to tell fetch to retry. */
454    ThreadID retryTid;
455
456    /** Cache block size. */
457    int cacheBlkSize;
458
459    /** Mask to get a cache block's address. */
460    Addr cacheBlkMask;
461
462    /** The cache line being fetched. */
463    uint8_t *cacheData[Impl::MaxThreads];
464
465    /** The PC of the cacheline that has been loaded. */
466    Addr cacheDataPC[Impl::MaxThreads];
467
468    /** Whether or not the cache data is valid. */
469    bool cacheDataValid[Impl::MaxThreads];
470
471    /** Size of instructions. */
472    int instSize;
473
474    /** Icache stall statistics. */
475    Counter lastIcacheStall[Impl::MaxThreads];
476
477    /** List of Active Threads */
478    std::list<ThreadID> *activeThreads;
479
480    /** Number of threads. */
481    ThreadID numThreads;
482
483    /** Number of threads that are actively fetching. */
484    ThreadID numFetchingThreads;
485
486    /** Thread ID being fetched. */
487    ThreadID threadFetched;
488
489    /** Checks if there is an interrupt pending.  If there is, fetch
490     * must stop once it is not fetching PAL instructions.
491     */
492    bool interruptPending;
493
494    /** Is there a drain pending. */
495    bool drainPending;
496
497    /** Records if fetch is switched out. */
498    bool switchedOut;
499
500    // @todo: Consider making these vectors and tracking on a per thread basis.
501    /** Stat for total number of cycles stalled due to an icache miss. */
502    Stats::Scalar icacheStallCycles;
503    /** Stat for total number of fetched instructions. */
504    Stats::Scalar fetchedInsts;
505    /** Total number of fetched branches. */
506    Stats::Scalar fetchedBranches;
507    /** Stat for total number of predicted branches. */
508    Stats::Scalar predictedBranches;
509    /** Stat for total number of cycles spent fetching. */
510    Stats::Scalar fetchCycles;
511    /** Stat for total number of cycles spent squashing. */
512    Stats::Scalar fetchSquashCycles;
513    /** Stat for total number of cycles spent waiting for translation */
514    Stats::Scalar fetchTlbCycles;
515    /** Stat for total number of cycles spent blocked due to other stages in
516     * the pipeline.
517     */
518    Stats::Scalar fetchIdleCycles;
519    /** Total number of cycles spent blocked. */
520    Stats::Scalar fetchBlockedCycles;
521    /** Total number of cycles spent in any other state. */
522    Stats::Scalar fetchMiscStallCycles;
523    /** Stat for total number of fetched cache lines. */
524    Stats::Scalar fetchedCacheLines;
525    /** Total number of outstanding icache accesses that were dropped
526     * due to a squash.
527     */
528    Stats::Scalar fetchIcacheSquashes;
529    /** Total number of outstanding tlb accesses that were dropped
530     * due to a squash.
531     */
532    Stats::Scalar fetchTlbSquashes;
533    /** Distribution of number of instructions fetched each cycle. */
534    Stats::Distribution fetchNisnDist;
535    /** Rate of how often fetch was idle. */
536    Stats::Formula idleRate;
537    /** Number of branch fetches per cycle. */
538    Stats::Formula branchRate;
539    /** Number of instruction fetched per cycle. */
540    Stats::Formula fetchRate;
541};
542
543#endif //__CPU_O3_FETCH_HH__
544