cpu.hh revision 2864:eab7ff8f6d72
16019Shines@cs.fsu.edu/*
212509Schuan.zhu@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
37093Sgblack@eecs.umich.edu * All rights reserved.
47093Sgblack@eecs.umich.edu *
57093Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67093Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77093Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97093Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117093Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127093Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137093Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
146019Shines@cs.fsu.edu * this software without specific prior written permission.
156019Shines@cs.fsu.edu *
166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276019Shines@cs.fsu.edu *
286019Shines@cs.fsu.edu * Authors: Kevin Lim
296019Shines@cs.fsu.edu *          Korey Sewell
306019Shines@cs.fsu.edu */
316019Shines@cs.fsu.edu
326019Shines@cs.fsu.edu#ifndef __CPU_O3_CPU_HH__
336019Shines@cs.fsu.edu#define __CPU_O3_CPU_HH__
346019Shines@cs.fsu.edu
356019Shines@cs.fsu.edu#include <iostream>
366019Shines@cs.fsu.edu#include <list>
376019Shines@cs.fsu.edu#include <queue>
386019Shines@cs.fsu.edu#include <set>
396019Shines@cs.fsu.edu#include <vector>
406019Shines@cs.fsu.edu
416735Sgblack@eecs.umich.edu#include "arch/isa_traits.hh"
426735Sgblack@eecs.umich.edu#include "base/statistics.hh"
4310037SARM gem5 Developers#include "base/timebuf.hh"
4410037SARM gem5 Developers#include "config/full_system.hh"
456019Shines@cs.fsu.edu#include "cpu/activity.hh"
466019Shines@cs.fsu.edu#include "cpu/base.hh"
476019Shines@cs.fsu.edu#include "cpu/simple_thread.hh"
4811793Sbrandon.potter@amd.com#include "cpu/o3/comm.hh"
4911793Sbrandon.potter@amd.com#include "cpu/o3/cpu_policy.hh"
5010037SARM gem5 Developers#include "cpu/o3/scoreboard.hh"
5110037SARM gem5 Developers#include "cpu/o3/thread_state.hh"
5210037SARM gem5 Developers//#include "cpu/o3/thread_context.hh"
538229Snate@binkert.org#include "sim/process.hh"
548229Snate@binkert.org
556019Shines@cs.fsu.edutemplate <class>
568232Snate@binkert.orgclass Checker;
578782Sgblack@eecs.umich.educlass ThreadContext;
586019Shines@cs.fsu.edutemplate <class>
596019Shines@cs.fsu.educlass O3ThreadContext;
606019Shines@cs.fsu.edu
616019Shines@cs.fsu.educlass Checkpoint;
6210037SARM gem5 Developersclass MemObject;
6310037SARM gem5 Developersclass Process;
6410037SARM gem5 Developers
6510037SARM gem5 Developersclass BaseO3CPU : public BaseCPU
6610037SARM gem5 Developers{
6710037SARM gem5 Developers    //Stuff that's pretty ISA independent will go here.
6810037SARM gem5 Developers  public:
6910037SARM gem5 Developers    typedef BaseCPU::Params Params;
7010037SARM gem5 Developers
7110037SARM gem5 Developers    BaseO3CPU(Params *params);
7210037SARM gem5 Developers
7310037SARM gem5 Developers    void regStats();
7410037SARM gem5 Developers
7510037SARM gem5 Developers    /** Sets this CPU's ID. */
7610037SARM gem5 Developers    void setCpuId(int id) { cpu_id = id; }
7710037SARM gem5 Developers
7810037SARM gem5 Developers    /** Reads this CPU's ID. */
7910037SARM gem5 Developers    int readCpuId() { return cpu_id; }
8010037SARM gem5 Developers
8110037SARM gem5 Developers  protected:
8210037SARM gem5 Developers    int cpu_id;
8310037SARM gem5 Developers};
8410037SARM gem5 Developers
8510037SARM gem5 Developers/**
8610037SARM gem5 Developers * FullO3CPU class, has each of the stages (fetch through commit)
8710037SARM gem5 Developers * within it, as well as all of the time buffers between stages.  The
8810037SARM gem5 Developers * tick() function for the CPU is defined here.
8910037SARM gem5 Developers */
9010037SARM gem5 Developerstemplate <class Impl>
9110037SARM gem5 Developersclass FullO3CPU : public BaseO3CPU
9210037SARM gem5 Developers{
9310037SARM gem5 Developers  public:
9410037SARM gem5 Developers    typedef TheISA::FloatReg FloatReg;
9510037SARM gem5 Developers    typedef TheISA::FloatRegBits FloatRegBits;
9610037SARM gem5 Developers
9710037SARM gem5 Developers    // Typedefs from the Impl here.
9810037SARM gem5 Developers    typedef typename Impl::CPUPol CPUPolicy;
9910037SARM gem5 Developers    typedef typename Impl::Params Params;
10010037SARM gem5 Developers    typedef typename Impl::DynInstPtr DynInstPtr;
10110037SARM gem5 Developers
1026019Shines@cs.fsu.edu    typedef O3ThreadState<Impl> Thread;
10310037SARM gem5 Developers
10410037SARM gem5 Developers    typedef typename std::list<DynInstPtr>::iterator ListIt;
10510037SARM gem5 Developers
1066019Shines@cs.fsu.edu    friend class O3ThreadContext<Impl>;
10710037SARM gem5 Developers
10810037SARM gem5 Developers  public:
10910037SARM gem5 Developers    enum Status {
11010037SARM gem5 Developers        Running,
11110037SARM gem5 Developers        Idle,
11210037SARM gem5 Developers        Halted,
11310037SARM gem5 Developers        Blocked,
11410037SARM gem5 Developers        SwitchedOut
11510037SARM gem5 Developers    };
11610037SARM gem5 Developers
11710037SARM gem5 Developers    /** Overall CPU status. */
11810037SARM gem5 Developers    Status _status;
11910037SARM gem5 Developers
12010037SARM gem5 Developers    /** Per-thread status in CPU, used for SMT.  */
12110037SARM gem5 Developers    Status _threadStatus[Impl::MaxThreads];
12210037SARM gem5 Developers
12310037SARM gem5 Developers  private:
12410037SARM gem5 Developers    class TickEvent : public Event
12510037SARM gem5 Developers    {
12610037SARM gem5 Developers      private:
12710037SARM gem5 Developers        /** Pointer to the CPU. */
12810037SARM gem5 Developers        FullO3CPU<Impl> *cpu;
12910037SARM gem5 Developers
13010037SARM gem5 Developers      public:
13110037SARM gem5 Developers        /** Constructs a tick event. */
13210037SARM gem5 Developers        TickEvent(FullO3CPU<Impl> *c);
13310037SARM gem5 Developers
13410037SARM gem5 Developers        /** Processes a tick event, calling tick() on the CPU. */
13510037SARM gem5 Developers        void process();
13610037SARM gem5 Developers        /** Returns the description of the tick event. */
13710037SARM gem5 Developers        const char *description();
13810037SARM gem5 Developers    };
13910037SARM gem5 Developers
14010037SARM gem5 Developers    /** The tick event used for scheduling CPU ticks. */
14110037SARM gem5 Developers    TickEvent tickEvent;
14210037SARM gem5 Developers
14310037SARM gem5 Developers    /** Schedule tick event, regardless of its current state. */
14410037SARM gem5 Developers    void scheduleTickEvent(int delay)
14510037SARM gem5 Developers    {
14610037SARM gem5 Developers        if (tickEvent.squashed())
1476019Shines@cs.fsu.edu            tickEvent.reschedule(curTick + cycles(delay));
14810037SARM gem5 Developers        else if (!tickEvent.scheduled())
14910037SARM gem5 Developers            tickEvent.schedule(curTick + cycles(delay));
15010037SARM gem5 Developers    }
1516019Shines@cs.fsu.edu
15210037SARM gem5 Developers    /** Unschedule tick event, regardless of its current state. */
15310037SARM gem5 Developers    void unscheduleTickEvent()
15410037SARM gem5 Developers    {
15510037SARM gem5 Developers        if (tickEvent.scheduled())
15610037SARM gem5 Developers            tickEvent.squash();
15710037SARM gem5 Developers    }
15810037SARM gem5 Developers
15910037SARM gem5 Developers    class ActivateThreadEvent : public Event
16010037SARM gem5 Developers    {
16110037SARM gem5 Developers      private:
16210037SARM gem5 Developers        /** Number of Thread to Activate */
16310037SARM gem5 Developers        int tid;
16410037SARM gem5 Developers
16510037SARM gem5 Developers        /** Pointer to the CPU. */
16610037SARM gem5 Developers        FullO3CPU<Impl> *cpu;
16710037SARM gem5 Developers
16810037SARM gem5 Developers      public:
16910037SARM gem5 Developers        /** Constructs the event. */
17010037SARM gem5 Developers        ActivateThreadEvent();
17110037SARM gem5 Developers
17210037SARM gem5 Developers        /** Initialize Event */
17310037SARM gem5 Developers        void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
17410037SARM gem5 Developers
17510037SARM gem5 Developers        /** Processes the event, calling activateThread() on the CPU. */
17610037SARM gem5 Developers        void process();
17710037SARM gem5 Developers
17810037SARM gem5 Developers        /** Returns the description of the event. */
17910037SARM gem5 Developers        const char *description();
18012571Sgiacomo.travaglini@arm.com    };
18110037SARM gem5 Developers
18210037SARM gem5 Developers    /** Schedule thread to activate , regardless of its current state. */
18310037SARM gem5 Developers    void scheduleActivateThreadEvent(int tid, int delay)
18410037SARM gem5 Developers    {
18510037SARM gem5 Developers        // Schedule thread to activate, regardless of its current state.
18610037SARM gem5 Developers        if (activateThreadEvent[tid].squashed())
18710037SARM gem5 Developers            activateThreadEvent[tid].reschedule(curTick + cycles(delay));
18810037SARM gem5 Developers        else if (!activateThreadEvent[tid].scheduled())
18910037SARM gem5 Developers            activateThreadEvent[tid].schedule(curTick + cycles(delay));
19010037SARM gem5 Developers    }
19110037SARM gem5 Developers
19210037SARM gem5 Developers    /** Unschedule actiavte thread event, regardless of its current state. */
1936019Shines@cs.fsu.edu    void unscheduleActivateThreadEvent(int tid)
19410037SARM gem5 Developers    {
19510037SARM gem5 Developers        if (activateThreadEvent[tid].scheduled())
19610037SARM gem5 Developers            activateThreadEvent[tid].squash();
1976019Shines@cs.fsu.edu    }
19810037SARM gem5 Developers
19910037SARM gem5 Developers    /** The tick event used for scheduling CPU ticks. */
20010037SARM gem5 Developers    ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
20112517Srekai.gonzalezalberquilla@arm.com
20210037SARM gem5 Developers  public:
20310037SARM gem5 Developers    /** Constructs a CPU with the given parameters. */
20410037SARM gem5 Developers    FullO3CPU(Params *params);
20512517Srekai.gonzalezalberquilla@arm.com    /** Destructor. */
20612517Srekai.gonzalezalberquilla@arm.com    ~FullO3CPU();
20712517Srekai.gonzalezalberquilla@arm.com
20810037SARM gem5 Developers    /** Registers statistics. */
20912517Srekai.gonzalezalberquilla@arm.com    void fullCPURegStats();
21012517Srekai.gonzalezalberquilla@arm.com
21112517Srekai.gonzalezalberquilla@arm.com    /** Ticks CPU, calling tick() on each stage, and checking the overall
21210037SARM gem5 Developers     *  activity to see if the CPU should deschedule itself.
21312517Srekai.gonzalezalberquilla@arm.com     */
21412517Srekai.gonzalezalberquilla@arm.com    void tick();
21512517Srekai.gonzalezalberquilla@arm.com
21610037SARM gem5 Developers    /** Initialize the CPU */
21712517Srekai.gonzalezalberquilla@arm.com    void init();
21812517Srekai.gonzalezalberquilla@arm.com
21912517Srekai.gonzalezalberquilla@arm.com    /** Returns the Number of Active Threads in the CPU */
22010037SARM gem5 Developers    int numActiveThreads()
22112517Srekai.gonzalezalberquilla@arm.com    { return activeThreads.size(); }
22212517Srekai.gonzalezalberquilla@arm.com
22312517Srekai.gonzalezalberquilla@arm.com    /** Add Thread to Active Threads List */
22410037SARM gem5 Developers    void activateThread(unsigned int tid);
22512517Srekai.gonzalezalberquilla@arm.com
22612517Srekai.gonzalezalberquilla@arm.com    /** Setup CPU to insert a thread's context */
22712517Srekai.gonzalezalberquilla@arm.com    void insertThread(unsigned tid);
22810037SARM gem5 Developers
22912517Srekai.gonzalezalberquilla@arm.com    /** Remove all of a thread's context from CPU */
23012517Srekai.gonzalezalberquilla@arm.com    void removeThread(unsigned tid);
23112517Srekai.gonzalezalberquilla@arm.com
23210037SARM gem5 Developers    /** Count the Total Instructions Committed in the CPU. */
23312517Srekai.gonzalezalberquilla@arm.com    virtual Counter totalInstructions() const
23412517Srekai.gonzalezalberquilla@arm.com    {
23512517Srekai.gonzalezalberquilla@arm.com        Counter total(0);
23610037SARM gem5 Developers
23710037SARM gem5 Developers        for (int i=0; i < thread.size(); i++)
23812517Srekai.gonzalezalberquilla@arm.com            total += thread[i]->numInst;
23912517Srekai.gonzalezalberquilla@arm.com
24012517Srekai.gonzalezalberquilla@arm.com        return total;
24112512Sgiacomo.travaglini@arm.com    }
24212517Srekai.gonzalezalberquilla@arm.com
24312517Srekai.gonzalezalberquilla@arm.com    /** Add Thread to Active Threads List. */
24412517Srekai.gonzalezalberquilla@arm.com    void activateContext(int tid, int delay);
24510037SARM gem5 Developers
24612517Srekai.gonzalezalberquilla@arm.com    /** Remove Thread from Active Threads List */
24712517Srekai.gonzalezalberquilla@arm.com    void suspendContext(int tid);
24812517Srekai.gonzalezalberquilla@arm.com
24910037SARM gem5 Developers    /** Remove Thread from Active Threads List &&
25012517Srekai.gonzalezalberquilla@arm.com     *  Remove Thread Context from CPU.
25112517Srekai.gonzalezalberquilla@arm.com     */
25212517Srekai.gonzalezalberquilla@arm.com    void deallocateContext(int tid);
25310037SARM gem5 Developers
25412517Srekai.gonzalezalberquilla@arm.com    /** Remove Thread from Active Threads List &&
25512517Srekai.gonzalezalberquilla@arm.com     *  Remove Thread Context from CPU.
25612517Srekai.gonzalezalberquilla@arm.com     */
25710037SARM gem5 Developers    void haltContext(int tid);
25812517Srekai.gonzalezalberquilla@arm.com
25912517Srekai.gonzalezalberquilla@arm.com    /** Activate a Thread When CPU Resources are Available. */
26012517Srekai.gonzalezalberquilla@arm.com    void activateWhenReady(int tid);
26110037SARM gem5 Developers
26210037SARM gem5 Developers    /** Add or Remove a Thread Context in the CPU. */
26312517Srekai.gonzalezalberquilla@arm.com    void doContextSwitch();
26412517Srekai.gonzalezalberquilla@arm.com
26512517Srekai.gonzalezalberquilla@arm.com    /** Update The Order In Which We Process Threads. */
26610037SARM gem5 Developers    void updateThreadPriority();
26710037SARM gem5 Developers
26812517Srekai.gonzalezalberquilla@arm.com    /** Serialize state. */
26912517Srekai.gonzalezalberquilla@arm.com    virtual void serialize(std::ostream &os);
27012517Srekai.gonzalezalberquilla@arm.com
27110037SARM gem5 Developers    /** Unserialize from a checkpoint. */
27210037SARM gem5 Developers    virtual void unserialize(Checkpoint *cp, const std::string &section);
27312517Srekai.gonzalezalberquilla@arm.com
27412517Srekai.gonzalezalberquilla@arm.com  public:
27512517Srekai.gonzalezalberquilla@arm.com    /** Executes a syscall on this cycle.
27610037SARM gem5 Developers     *  ---------------------------------------
27710037SARM gem5 Developers     *  Note: this is a virtual function. CPU-Specific
27812517Srekai.gonzalezalberquilla@arm.com     *  functionality defined in derived classes
27912517Srekai.gonzalezalberquilla@arm.com     */
28012517Srekai.gonzalezalberquilla@arm.com    virtual void syscall(int tid) { panic("Unimplemented!"); }
28112299Sandreas.sandberg@arm.com
28212299Sandreas.sandberg@arm.com    /** Starts draining the CPU's pipeline of all instructions in
28312517Srekai.gonzalezalberquilla@arm.com     * order to stop all memory accesses. */
28412517Srekai.gonzalezalberquilla@arm.com    virtual bool drain(Event *drain_event);
28512517Srekai.gonzalezalberquilla@arm.com
28610037SARM gem5 Developers    /** Resumes execution after a drain. */
28710037SARM gem5 Developers    virtual void resume();
28812517Srekai.gonzalezalberquilla@arm.com
28912517Srekai.gonzalezalberquilla@arm.com    /** Signals to this CPU that a stage has completed switching out. */
29012517Srekai.gonzalezalberquilla@arm.com    void signalDrained();
29110037SARM gem5 Developers
29210037SARM gem5 Developers    /** Switches out this CPU. */
29312517Srekai.gonzalezalberquilla@arm.com    virtual void switchOut();
29412517Srekai.gonzalezalberquilla@arm.com
2956019Shines@cs.fsu.edu    /** Takes over from another CPU. */
29610037SARM gem5 Developers    virtual void takeOverFrom(BaseCPU *oldCPU);
2977362Sgblack@eecs.umich.edu
2986735Sgblack@eecs.umich.edu    /** Get the current instruction sequence number, and increment it. */
29910037SARM gem5 Developers    InstSeqNum getAndIncrementInstSeq()
3006019Shines@cs.fsu.edu    { return globalSeqNum++; }
30110037SARM gem5 Developers
30210037SARM gem5 Developers#if FULL_SYSTEM
3037400SAli.Saidi@ARM.com    /** Check if this address is a valid instruction address. */
3046735Sgblack@eecs.umich.edu    bool validInstAddr(Addr addr) { return true; }
3056735Sgblack@eecs.umich.edu
30610037SARM gem5 Developers    /** Check if this address is a valid data address. */
3076735Sgblack@eecs.umich.edu    bool validDataAddr(Addr addr) { return true; }
30810037SARM gem5 Developers
30910037SARM gem5 Developers    /** Get instruction asid. */
31010037SARM gem5 Developers    int getInstAsid(unsigned tid)
31110037SARM gem5 Developers    { return regFile.miscRegs[tid].getInstAsid(); }
3127400SAli.Saidi@ARM.com
31310037SARM gem5 Developers    /** Get data asid. */
31410037SARM gem5 Developers    int getDataAsid(unsigned tid)
31510037SARM gem5 Developers    { return regFile.miscRegs[tid].getDataAsid(); }
31610037SARM gem5 Developers#else
31710037SARM gem5 Developers    /** Get instruction asid. */
31810037SARM gem5 Developers    int getInstAsid(unsigned tid)
31910037SARM gem5 Developers    { return thread[tid]->getInstAsid(); }
32010037SARM gem5 Developers
32110037SARM gem5 Developers    /** Get data asid. */
32210037SARM gem5 Developers    int getDataAsid(unsigned tid)
32310037SARM gem5 Developers    { return thread[tid]->getDataAsid(); }
32410037SARM gem5 Developers
32510037SARM gem5 Developers#endif
32610037SARM gem5 Developers
32710037SARM gem5 Developers    /** Register accessors.  Index refers to the physical register index. */
32810037SARM gem5 Developers    uint64_t readIntReg(int reg_idx);
32910037SARM gem5 Developers
3306019Shines@cs.fsu.edu    FloatReg readFloatReg(int reg_idx);
3316019Shines@cs.fsu.edu
33210037SARM gem5 Developers    FloatReg readFloatReg(int reg_idx, int width);
33310037SARM gem5 Developers
33410037SARM gem5 Developers    FloatRegBits readFloatRegBits(int reg_idx);
33510037SARM gem5 Developers
33610037SARM gem5 Developers    FloatRegBits readFloatRegBits(int reg_idx, int width);
33710037SARM gem5 Developers
33810037SARM gem5 Developers    void setIntReg(int reg_idx, uint64_t val);
33910037SARM gem5 Developers
34010037SARM gem5 Developers    void setFloatReg(int reg_idx, FloatReg val);
34111574SCurtis.Dunham@arm.com
34211574SCurtis.Dunham@arm.com    void setFloatReg(int reg_idx, FloatReg val, int width);
34311574SCurtis.Dunham@arm.com
34411574SCurtis.Dunham@arm.com    void setFloatRegBits(int reg_idx, FloatRegBits val);
34510037SARM gem5 Developers
34610037SARM gem5 Developers    void setFloatRegBits(int reg_idx, FloatRegBits val, int width);
34710037SARM gem5 Developers
34810037SARM gem5 Developers    uint64_t readArchIntReg(int reg_idx, unsigned tid);
34910037SARM gem5 Developers
35010037SARM gem5 Developers    float readArchFloatRegSingle(int reg_idx, unsigned tid);
35110037SARM gem5 Developers
35212511Schuan.zhu@arm.com    double readArchFloatRegDouble(int reg_idx, unsigned tid);
35310037SARM gem5 Developers
35410037SARM gem5 Developers    uint64_t readArchFloatRegInt(int reg_idx, unsigned tid);
35510037SARM gem5 Developers
35610037SARM gem5 Developers    /** Architectural register accessors.  Looks up in the commit
35710037SARM gem5 Developers     * rename table to obtain the true physical index of the
35810037SARM gem5 Developers     * architected register first, then accesses that physical
35910037SARM gem5 Developers     * register.
36010037SARM gem5 Developers     */
36110037SARM gem5 Developers    void setArchIntReg(int reg_idx, uint64_t val, unsigned tid);
36210037SARM gem5 Developers
36310037SARM gem5 Developers    void setArchFloatRegSingle(int reg_idx, float val, unsigned tid);
36410037SARM gem5 Developers
36510037SARM gem5 Developers    void setArchFloatRegDouble(int reg_idx, double val, unsigned tid);
36610037SARM gem5 Developers
36710037SARM gem5 Developers    void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid);
36810037SARM gem5 Developers
36910037SARM gem5 Developers    /** Reads the commit PC of a specific thread. */
37010037SARM gem5 Developers    uint64_t readPC(unsigned tid);
37110037SARM gem5 Developers
37210037SARM gem5 Developers    /** Sets the commit PC of a specific thread. */
37310037SARM gem5 Developers    void setPC(Addr new_PC, unsigned tid);
37410037SARM gem5 Developers
37510037SARM gem5 Developers    /** Reads the next PC of a specific thread. */
37610037SARM gem5 Developers    uint64_t readNextPC(unsigned tid);
37710037SARM gem5 Developers
37810037SARM gem5 Developers    /** Sets the next PC of a specific thread. */
37910037SARM gem5 Developers    void setNextPC(uint64_t val, unsigned tid);
38010037SARM gem5 Developers
38110037SARM gem5 Developers    /** Reads the next NPC of a specific thread. */
38210037SARM gem5 Developers    uint64_t readNextNPC(unsigned tid);
38310037SARM gem5 Developers
38410037SARM gem5 Developers    /** Sets the next NPC of a specific thread. */
38510037SARM gem5 Developers    void setNextNPC(uint64_t val, unsigned tid);
38610037SARM gem5 Developers
38710037SARM gem5 Developers    /** Function to add instruction onto the head of the list of the
38810037SARM gem5 Developers     *  instructions.  Used when new instructions are fetched.
38910037SARM gem5 Developers     */
39010037SARM gem5 Developers    ListIt addInst(DynInstPtr &inst);
39110037SARM gem5 Developers
39210037SARM gem5 Developers    /** Function to tell the CPU that an instruction has completed. */
39312402Sgiacomo.travaglini@arm.com    void instDone(unsigned tid);
39410037SARM gem5 Developers
39510037SARM gem5 Developers    /** Add Instructions to the CPU Remove List*/
39610037SARM gem5 Developers    void addToRemoveList(DynInstPtr &inst);
39710037SARM gem5 Developers
39810037SARM gem5 Developers    /** Remove an instruction from the front end of the list.  There's
39910037SARM gem5 Developers     *  no restriction on location of the instruction.
40010037SARM gem5 Developers     */
40110037SARM gem5 Developers    void removeFrontInst(DynInstPtr &inst);
40210037SARM gem5 Developers
40310037SARM gem5 Developers    /** Remove all instructions that are not currently in the ROB. */
40410037SARM gem5 Developers    void removeInstsNotInROB(unsigned tid);
40510037SARM gem5 Developers
40610037SARM gem5 Developers    /** Remove all instructions younger than the given sequence number. */
40710037SARM gem5 Developers    void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
40810037SARM gem5 Developers
40910037SARM gem5 Developers    /** Removes the instruction pointed to by the iterator. */
41010037SARM gem5 Developers    inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
41110037SARM gem5 Developers
41210037SARM gem5 Developers    /** Cleans up all instructions on the remove list. */
41310037SARM gem5 Developers    void cleanUpRemovedInsts();
41410037SARM gem5 Developers
41510037SARM gem5 Developers    /** Debug function to print all instructions on the list. */
41610037SARM gem5 Developers    void dumpInsts();
41710037SARM gem5 Developers
41810037SARM gem5 Developers  public:
41910037SARM gem5 Developers    /** List of all the instructions in flight. */
42010037SARM gem5 Developers    std::list<DynInstPtr> instList;
42110037SARM gem5 Developers
42210037SARM gem5 Developers    /** List of all the instructions that will be removed at the end of this
42310037SARM gem5 Developers     *  cycle.
42410037SARM gem5 Developers     */
42510037SARM gem5 Developers    std::queue<ListIt> removeList;
42610037SARM gem5 Developers
42710037SARM gem5 Developers#ifdef DEBUG
42810037SARM gem5 Developers    /** Debug structure to keep track of the sequence numbers still in
42912569Sgiacomo.travaglini@arm.com     * flight.
4306019Shines@cs.fsu.edu     */
43110037SARM gem5 Developers    std::set<InstSeqNum> snList;
43210037SARM gem5 Developers#endif
43312569Sgiacomo.travaglini@arm.com
43412569Sgiacomo.travaglini@arm.com    /** Records if instructions need to be removed this cycle due to
43512569Sgiacomo.travaglini@arm.com     *  being retired or squashed.
43612569Sgiacomo.travaglini@arm.com     */
43712569Sgiacomo.travaglini@arm.com    bool removeInstsThisCycle;
43810037SARM gem5 Developers
43912569Sgiacomo.travaglini@arm.com  protected:
44012569Sgiacomo.travaglini@arm.com    /** The fetch stage. */
44112569Sgiacomo.travaglini@arm.com    typename CPUPolicy::Fetch fetch;
44212569Sgiacomo.travaglini@arm.com
44312569Sgiacomo.travaglini@arm.com    /** The decode stage. */
44412569Sgiacomo.travaglini@arm.com    typename CPUPolicy::Decode decode;
44512569Sgiacomo.travaglini@arm.com
44612569Sgiacomo.travaglini@arm.com    /** The dispatch stage. */
44712569Sgiacomo.travaglini@arm.com    typename CPUPolicy::Rename rename;
44812569Sgiacomo.travaglini@arm.com
44912569Sgiacomo.travaglini@arm.com    /** The issue/execute/writeback stages. */
45012569Sgiacomo.travaglini@arm.com    typename CPUPolicy::IEW iew;
45112569Sgiacomo.travaglini@arm.com
45212402Sgiacomo.travaglini@arm.com    /** The commit stage. */
45312569Sgiacomo.travaglini@arm.com    typename CPUPolicy::Commit commit;
45412569Sgiacomo.travaglini@arm.com
45510037SARM gem5 Developers    /** The register file. */
45612569Sgiacomo.travaglini@arm.com    typename CPUPolicy::RegFile regFile;
45712569Sgiacomo.travaglini@arm.com
45812569Sgiacomo.travaglini@arm.com    /** The free list. */
45912569Sgiacomo.travaglini@arm.com    typename CPUPolicy::FreeList freeList;
46012569Sgiacomo.travaglini@arm.com
46112569Sgiacomo.travaglini@arm.com    /** The rename map. */
46212569Sgiacomo.travaglini@arm.com    typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads];
46312569Sgiacomo.travaglini@arm.com
46412569Sgiacomo.travaglini@arm.com    /** The commit rename map. */
46512569Sgiacomo.travaglini@arm.com    typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads];
46612569Sgiacomo.travaglini@arm.com
46712569Sgiacomo.travaglini@arm.com    /** The re-order buffer. */
46812569Sgiacomo.travaglini@arm.com    typename CPUPolicy::ROB rob;
46912569Sgiacomo.travaglini@arm.com
47012569Sgiacomo.travaglini@arm.com    /** Active Threads List */
47112569Sgiacomo.travaglini@arm.com    std::list<unsigned> activeThreads;
47212569Sgiacomo.travaglini@arm.com
47312569Sgiacomo.travaglini@arm.com    /** Integer Register Scoreboard */
47412569Sgiacomo.travaglini@arm.com    Scoreboard scoreboard;
47512569Sgiacomo.travaglini@arm.com
47612569Sgiacomo.travaglini@arm.com  public:
47710037SARM gem5 Developers    /** Enum to give each stage a specific index, so when calling
47810037SARM gem5 Developers     *  activateStage() or deactivateStage(), they can specify which stage
47910037SARM gem5 Developers     *  is being activated/deactivated.
48010037SARM gem5 Developers     */
48110037SARM gem5 Developers    enum StageIdx {
48210037SARM gem5 Developers        FetchIdx,
48310037SARM gem5 Developers        DecodeIdx,
4846735Sgblack@eecs.umich.edu        RenameIdx,
4858782Sgblack@eecs.umich.edu        IEWIdx,
4868782Sgblack@eecs.umich.edu        CommitIdx,
4876735Sgblack@eecs.umich.edu        NumStages };
4886019Shines@cs.fsu.edu
4896735Sgblack@eecs.umich.edu    /** Typedefs from the Impl to get the structs that each of the
49010037SARM gem5 Developers     *  time buffers should use.
4918303SAli.Saidi@ARM.com     */
49210338SCurtis.Dunham@arm.com    typedef typename CPUPolicy::TimeStruct TimeStruct;
49310338SCurtis.Dunham@arm.com
49410338SCurtis.Dunham@arm.com    typedef typename CPUPolicy::FetchStruct FetchStruct;
49510338SCurtis.Dunham@arm.com
4968303SAli.Saidi@ARM.com    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
4977720Sgblack@eecs.umich.edu
4988205SAli.Saidi@ARM.com    typedef typename CPUPolicy::RenameStruct RenameStruct;
4998205SAli.Saidi@ARM.com
5008205SAli.Saidi@ARM.com    typedef typename CPUPolicy::IEWStruct IEWStruct;
5016735Sgblack@eecs.umich.edu
50210037SARM gem5 Developers    /** The main time buffer to do backwards communication. */
50310037SARM gem5 Developers    TimeBuffer<TimeStruct> timeBuffer;
50410037SARM gem5 Developers
50510037SARM gem5 Developers    /** The fetch stage's instruction queue. */
50612398Sgiacomo.travaglini@arm.com    TimeBuffer<FetchStruct> fetchQueue;
50710037SARM gem5 Developers
50810037SARM gem5 Developers    /** The decode stage's instruction queue. */
50910037SARM gem5 Developers    TimeBuffer<DecodeStruct> decodeQueue;
51010037SARM gem5 Developers
51110037SARM gem5 Developers    /** The rename stage's instruction queue. */
51210037SARM gem5 Developers    TimeBuffer<RenameStruct> renameQueue;
51310037SARM gem5 Developers
51410037SARM gem5 Developers    /** The IEW stage's instruction queue. */
51510037SARM gem5 Developers    TimeBuffer<IEWStruct> iewQueue;
51610037SARM gem5 Developers
51710037SARM gem5 Developers  private:
51810037SARM gem5 Developers    /** The activity recorder; used to tell if the CPU has any
51912569Sgiacomo.travaglini@arm.com     * activity remaining or if it can go to idle and deschedule
52012569Sgiacomo.travaglini@arm.com     * itself.
52112569Sgiacomo.travaglini@arm.com     */
52210037SARM gem5 Developers    ActivityRecorder activityRec;
52310037SARM gem5 Developers
52410037SARM gem5 Developers  public:
52510037SARM gem5 Developers    /** Records that there was time buffer activity this cycle. */
52610037SARM gem5 Developers    void activityThisCycle() { activityRec.activity(); }
52710037SARM gem5 Developers
52810037SARM gem5 Developers    /** Changes a stage's status to active within the activity recorder. */
52910037SARM gem5 Developers    void activateStage(const StageIdx idx)
53010037SARM gem5 Developers    { activityRec.activateStage(idx); }
53110037SARM gem5 Developers
53210037SARM gem5 Developers    /** Changes a stage's status to inactive within the activity recorder. */
53310037SARM gem5 Developers    void deactivateStage(const StageIdx idx)
53410037SARM gem5 Developers    { activityRec.deactivateStage(idx); }
53510037SARM gem5 Developers
53610037SARM gem5 Developers    /** Wakes the CPU, rescheduling the CPU if it's not already active. */
53710037SARM gem5 Developers    void wakeCPU();
53810037SARM gem5 Developers
53910037SARM gem5 Developers    /** Gets a free thread id. Use if thread ids change across system. */
54010037SARM gem5 Developers    int getFreeTid();
54110037SARM gem5 Developers
54210037SARM gem5 Developers  public:
54310037SARM gem5 Developers    /** Returns a pointer to a thread context. */
54410037SARM gem5 Developers    ThreadContext *tcBase(unsigned tid)
54510037SARM gem5 Developers    {
5466735Sgblack@eecs.umich.edu        return thread[tid]->getTC();
5476735Sgblack@eecs.umich.edu    }
5486735Sgblack@eecs.umich.edu
54910037SARM gem5 Developers    /** The global sequence number counter. */
5508518Sgeoffrey.blake@arm.com    InstSeqNum globalSeqNum;
5518518Sgeoffrey.blake@arm.com
5526735Sgblack@eecs.umich.edu    /** Pointer to the checker, which can dynamically verify
55310037SARM gem5 Developers     * instruction results at run time.  This can be set to NULL if it
55410037SARM gem5 Developers     * is not being used.
55510037SARM gem5 Developers     */
55610037SARM gem5 Developers    Checker<DynInstPtr> *checker;
55710037SARM gem5 Developers
55810037SARM gem5 Developers#if FULL_SYSTEM
55910037SARM gem5 Developers    /** Pointer to the system. */
56010037SARM gem5 Developers    System *system;
56110037SARM gem5 Developers
56210037SARM gem5 Developers    /** Pointer to physical memory. */
56310037SARM gem5 Developers    PhysicalMemory *physmem;
56410037SARM gem5 Developers#endif
5656735Sgblack@eecs.umich.edu
5666735Sgblack@eecs.umich.edu    /** Pointer to memory. */
5676735Sgblack@eecs.umich.edu    MemObject *mem;
5686735Sgblack@eecs.umich.edu
5696735Sgblack@eecs.umich.edu    /** Event to call process() on once draining has completed. */
5706735Sgblack@eecs.umich.edu    Event *drainEvent;
5716735Sgblack@eecs.umich.edu
5726735Sgblack@eecs.umich.edu    /** Counter of how many stages have completed draining. */
5736735Sgblack@eecs.umich.edu    int drainCount;
57410037SARM gem5 Developers
57510037SARM gem5 Developers    /** Pointers to all of the threads in the CPU. */
57610037SARM gem5 Developers    std::vector<Thread *> thread;
5776735Sgblack@eecs.umich.edu
5786735Sgblack@eecs.umich.edu    /** Pointer to the icache interface. */
5796735Sgblack@eecs.umich.edu    MemInterface *icacheInterface;
5806735Sgblack@eecs.umich.edu    /** Pointer to the dcache interface. */
58110037SARM gem5 Developers    MemInterface *dcacheInterface;
58210037SARM gem5 Developers
58310037SARM gem5 Developers    /** Whether or not the CPU should defer its registration. */
58410037SARM gem5 Developers    bool deferRegistration;
58510037SARM gem5 Developers
58610037SARM gem5 Developers    /** Is there a context switch pending? */
58710037SARM gem5 Developers    bool contextSwitch;
58810037SARM gem5 Developers
58910037SARM gem5 Developers    /** Threads Scheduled to Enter CPU */
59010037SARM gem5 Developers    std::list<int> cpuWaitList;
5916735Sgblack@eecs.umich.edu
5926735Sgblack@eecs.umich.edu    /** The cycle that the CPU was last running, used for statistics. */
5937093Sgblack@eecs.umich.edu    Tick lastRunningCycle;
5947093Sgblack@eecs.umich.edu
5957720Sgblack@eecs.umich.edu    /** The cycle that the CPU was last activated by a new thread*/
5967585SAli.Saidi@arm.com    Tick lastActivatedCycle;
5977720Sgblack@eecs.umich.edu
5987720Sgblack@eecs.umich.edu    /** Number of Threads CPU can process */
5997720Sgblack@eecs.umich.edu    unsigned numThreads;
6007720Sgblack@eecs.umich.edu
6017720Sgblack@eecs.umich.edu    /** Mapping for system thread id to cpu id */
6027720Sgblack@eecs.umich.edu    std::map<unsigned,unsigned> threadMap;
60310037SARM gem5 Developers
60410037SARM gem5 Developers    /** Available thread ids in the cpu*/
6057720Sgblack@eecs.umich.edu    std::vector<unsigned> tids;
6066019Shines@cs.fsu.edu
6077189Sgblack@eecs.umich.edu    /** Stat for total number of times the CPU is descheduled. */
6087400SAli.Saidi@ARM.com    Stats::Scalar<> timesIdled;
60910417Sandreas.hansson@arm.com    /** Stat for total number of cycles the CPU spends descheduled. */
61010037SARM gem5 Developers    Stats::Scalar<> idleCycles;
61110037SARM gem5 Developers    /** Stat for the number of committed instructions per thread. */
61210037SARM gem5 Developers    Stats::Vector<> committedInsts;
61310037SARM gem5 Developers    /** Stat for the total number of committed instructions. */
61410037SARM gem5 Developers    Stats::Scalar<> totalCommittedInsts;
61510037SARM gem5 Developers    /** Stat for the CPI per thread. */
61610037SARM gem5 Developers    Stats::Formula cpi;
61710037SARM gem5 Developers    /** Stat for the total CPI. */
61811574SCurtis.Dunham@arm.com    Stats::Formula totalCpi;
61911574SCurtis.Dunham@arm.com    /** Stat for the IPC per thread. */
62011574SCurtis.Dunham@arm.com    Stats::Formula ipc;
62111574SCurtis.Dunham@arm.com    /** Stat for the total IPC. */
62211574SCurtis.Dunham@arm.com    Stats::Formula totalIpc;
62310037SARM gem5 Developers};
62410037SARM gem5 Developers
62510037SARM gem5 Developers#endif // __CPU_O3_CPU_HH__
62610037SARM gem5 Developers