cpu.hh revision 4632
12SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim
292665Ssaidi@eecs.umich.edu *          Korey Sewell
302665Ssaidi@eecs.umich.edu */
312SN/A
322SN/A#ifndef __CPU_O3_CPU_HH__
332SN/A#define __CPU_O3_CPU_HH__
342SN/A
352SN/A#include <iostream>
362SN/A#include <list>
373971Sgblack@eecs.umich.edu#include <queue>
3856SN/A#include <set>
3956SN/A#include <vector>
401158SN/A
41146SN/A#include "arch/types.hh"
421858SN/A#include "base/statistics.hh"
432680Sktlim@umich.edu#include "base/timebuf.hh"
442378SN/A#include "config/full_system.hh"
452522SN/A#include "cpu/activity.hh"
462401SN/A#include "cpu/base.hh"
475154Sgblack@eecs.umich.edu#include "cpu/simple_thread.hh"
484762Snate@binkert.org#include "cpu/o3/comm.hh"
495512SMichael.Adler@intel.com#include "cpu/o3/cpu_policy.hh"
50360SN/A#include "cpu/o3/scoreboard.hh"
514434Ssaidi@eecs.umich.edu#include "cpu/o3/thread_state.hh"
52695SN/A//#include "cpu/o3/thread_context.hh"
532093SN/A#include "sim/process.hh"
542378SN/A
552SN/Atemplate <class>
562715Sstever@eecs.umich.educlass Checker;
572715Sstever@eecs.umich.educlass ThreadContext;
582715Sstever@eecs.umich.edutemplate <class>
592715Sstever@eecs.umich.educlass O3ThreadContext;
602715Sstever@eecs.umich.edu
612715Sstever@eecs.umich.educlass Checkpoint;
622715Sstever@eecs.umich.educlass MemObject;
632715Sstever@eecs.umich.educlass Process;
642715Sstever@eecs.umich.edu
655335Shines@cs.fsu.educlass BaseO3CPU : public BaseCPU
665335Shines@cs.fsu.edu{
674157Sgblack@eecs.umich.edu    //Stuff that's pretty ISA independent will go here.
684166Sgblack@eecs.umich.edu  public:
692715Sstever@eecs.umich.edu    typedef BaseCPU::Params Params;
702715Sstever@eecs.umich.edu
712715Sstever@eecs.umich.edu    BaseO3CPU(Params *params);
722715Sstever@eecs.umich.edu
732715Sstever@eecs.umich.edu    void regStats();
742SN/A
752107SN/A    /** Sets this CPU's ID. */
762SN/A    void setCpuId(int id) { cpu_id = id; }
772SN/A
782SN/A    /** Reads this CPU's ID. */
792SN/A    int readCpuId() { return cpu_id; }
802SN/A
812SN/A  protected:
821858SN/A    int cpu_id;
83360SN/A};
842SN/A
852SN/A/**
862SN/A * FullO3CPU class, has each of the stages (fetch through commit)
872SN/A * within it, as well as all of the time buffers between stages.  The
882SN/A * tick() function for the CPU is defined here.
895758Shsul@eecs.umich.edu */
905771Shsul@eecs.umich.edutemplate <class Impl>
915758Shsul@eecs.umich.educlass FullO3CPU : public BaseO3CPU
925758Shsul@eecs.umich.edu{
935758Shsul@eecs.umich.edu  public:
945758Shsul@eecs.umich.edu    // Typedefs from the Impl here.
955758Shsul@eecs.umich.edu    typedef typename Impl::CPUPol CPUPolicy;
965771Shsul@eecs.umich.edu    typedef typename Impl::Params Params;
975771Shsul@eecs.umich.edu    typedef typename Impl::DynInstPtr DynInstPtr;
985758Shsul@eecs.umich.edu    typedef typename Impl::O3CPU O3CPU;
995154Sgblack@eecs.umich.edu
1005183Ssaidi@eecs.umich.edu    typedef O3ThreadState<Impl> Thread;
1015154Sgblack@eecs.umich.edu
1022SN/A    typedef typename std::list<DynInstPtr>::iterator ListIt;
1035154Sgblack@eecs.umich.edu
1045154Sgblack@eecs.umich.edu    friend class O3ThreadContext<Impl>;
1055514SMichael.Adler@intel.com
1065154Sgblack@eecs.umich.edu  public:
1075154Sgblack@eecs.umich.edu    enum Status {
1085154Sgblack@eecs.umich.edu        Running,
1095154Sgblack@eecs.umich.edu        Idle,
1105154Sgblack@eecs.umich.edu        Halted,
1115154Sgblack@eecs.umich.edu        Blocked,
1125154Sgblack@eecs.umich.edu        SwitchedOut
1135154Sgblack@eecs.umich.edu    };
1145154Sgblack@eecs.umich.edu
1155154Sgblack@eecs.umich.edu#if FULL_SYSTEM
1165154Sgblack@eecs.umich.edu    TheISA::ITB * itb;
1175154Sgblack@eecs.umich.edu    TheISA::DTB * dtb;
1185154Sgblack@eecs.umich.edu#endif
1195154Sgblack@eecs.umich.edu
1205154Sgblack@eecs.umich.edu    /** Overall CPU status. */
1215154Sgblack@eecs.umich.edu    Status _status;
1225154Sgblack@eecs.umich.edu
1235154Sgblack@eecs.umich.edu    /** Per-thread status in CPU, used for SMT.  */
1245154Sgblack@eecs.umich.edu    Status _threadStatus[Impl::MaxThreads];
1255154Sgblack@eecs.umich.edu
1265514SMichael.Adler@intel.com  private:
1275514SMichael.Adler@intel.com    class TickEvent : public Event
1285514SMichael.Adler@intel.com    {
1295514SMichael.Adler@intel.com      private:
1305514SMichael.Adler@intel.com        /** Pointer to the CPU. */
1315514SMichael.Adler@intel.com        FullO3CPU<Impl> *cpu;
1325514SMichael.Adler@intel.com
1335514SMichael.Adler@intel.com      public:
1345514SMichael.Adler@intel.com        /** Constructs a tick event. */
1355514SMichael.Adler@intel.com        TickEvent(FullO3CPU<Impl> *c);
1365154Sgblack@eecs.umich.edu
1374997Sgblack@eecs.umich.edu        /** Processes a tick event, calling tick() on the CPU. */
1382SN/A        void process();
1395282Srstrong@cs.ucsd.edu        /** Returns the description of the tick event. */
1405282Srstrong@cs.ucsd.edu        const char *description();
1415282Srstrong@cs.ucsd.edu    };
1425282Srstrong@cs.ucsd.edu
1435282Srstrong@cs.ucsd.edu    /** The tick event used for scheduling CPU ticks. */
1445282Srstrong@cs.ucsd.edu    TickEvent tickEvent;
1455282Srstrong@cs.ucsd.edu
1465282Srstrong@cs.ucsd.edu    /** Schedule tick event, regardless of its current state. */
1475282Srstrong@cs.ucsd.edu    void scheduleTickEvent(int delay)
1485282Srstrong@cs.ucsd.edu    {
1495282Srstrong@cs.ucsd.edu        if (tickEvent.squashed())
1505282Srstrong@cs.ucsd.edu            tickEvent.reschedule(nextCycle(curTick + cycles(delay)));
1515282Srstrong@cs.ucsd.edu        else if (!tickEvent.scheduled())
1525282Srstrong@cs.ucsd.edu            tickEvent.schedule(nextCycle(curTick + cycles(delay)));
1535282Srstrong@cs.ucsd.edu    }
1545282Srstrong@cs.ucsd.edu
1555514SMichael.Adler@intel.com    /** Unschedule tick event, regardless of its current state. */
1565282Srstrong@cs.ucsd.edu    void unscheduleTickEvent()
1575282Srstrong@cs.ucsd.edu    {
1585282Srstrong@cs.ucsd.edu        if (tickEvent.scheduled())
1595282Srstrong@cs.ucsd.edu            tickEvent.squash();
1602SN/A    }
1612SN/A
1622SN/A    class ActivateThreadEvent : public Event
1635282Srstrong@cs.ucsd.edu    {
1645282Srstrong@cs.ucsd.edu      private:
1652SN/A        /** Number of Thread to Activate */
1662SN/A        int tid;
1671450SN/A
1681514SN/A        /** Pointer to the CPU. */
1695184Sgblack@eecs.umich.edu        FullO3CPU<Impl> *cpu;
1702SN/A
1712SN/A      public:
1722SN/A        /** Constructs the event. */
1732378SN/A        ActivateThreadEvent();
1742SN/A
1752SN/A        /** Initialize Event */
1762SN/A        void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
177729SN/A
1782SN/A        /** Processes the event, calling activateThread() on the CPU. */
1792SN/A        void process();
1802SN/A
1812SN/A        /** Returns the description of the event. */
1822SN/A        const char *description();
1832SN/A    };
1842SN/A
1852SN/A    /** Schedule thread to activate , regardless of its current state. */
1862SN/A    void scheduleActivateThreadEvent(int tid, int delay)
1872SN/A    {
1882SN/A        // Schedule thread to activate, regardless of its current state.
1892SN/A        if (activateThreadEvent[tid].squashed())
1902SN/A            activateThreadEvent[tid].
1912SN/A                reschedule(nextCycle(curTick + cycles(delay)));
1922SN/A        else if (!activateThreadEvent[tid].scheduled())
1932SN/A            activateThreadEvent[tid].
1942SN/A                schedule(nextCycle(curTick + cycles(delay)));
1952SN/A    }
1962SN/A
1972SN/A    /** Unschedule actiavte thread event, regardless of its current state. */
1982SN/A    void unscheduleActivateThreadEvent(int tid)
1992SN/A    {
2002SN/A        if (activateThreadEvent[tid].scheduled())
2012SN/A            activateThreadEvent[tid].squash();
2022SN/A    }
2032SN/A
2042SN/A    /** The tick event used for scheduling CPU ticks. */
2052SN/A    ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
2065514SMichael.Adler@intel.com
2072SN/A    class DeallocateContextEvent : public Event
2082SN/A    {
2092SN/A      private:
2102SN/A        /** Number of Thread to deactivate */
2112SN/A        int tid;
2122SN/A
2132SN/A        /** Should the thread be removed from the CPU? */
2142SN/A        bool remove;
2152SN/A
2162SN/A        /** Pointer to the CPU. */
2175713Shsul@eecs.umich.edu        FullO3CPU<Impl> *cpu;
2185713Shsul@eecs.umich.edu
2192SN/A      public:
2205713Shsul@eecs.umich.edu        /** Constructs the event. */
2215713Shsul@eecs.umich.edu        DeallocateContextEvent();
2225713Shsul@eecs.umich.edu
2235713Shsul@eecs.umich.edu        /** Initialize Event */
2245713Shsul@eecs.umich.edu        void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
2255713Shsul@eecs.umich.edu
2265713Shsul@eecs.umich.edu        /** Processes the event, calling activateThread() on the CPU. */
2275713Shsul@eecs.umich.edu        void process();
2285512SMichael.Adler@intel.com
2295713Shsul@eecs.umich.edu        /** Sets whether the thread should also be removed from the CPU. */
2302SN/A        void setRemove(bool _remove) { remove = _remove; }
2312SN/A
2321395SN/A        /** Returns the description of the event. */
2331395SN/A        const char *description();
2341395SN/A    };
2355713Shsul@eecs.umich.edu
2365713Shsul@eecs.umich.edu    /** Schedule cpu to deallocate thread context.*/
2372378SN/A    void scheduleDeallocateContextEvent(int tid, bool remove, int delay)
2382680Sktlim@umich.edu    {
2395713Shsul@eecs.umich.edu        // Schedule thread to activate, regardless of its current state.
2401395SN/A        if (deallocateContextEvent[tid].squashed())
2411634SN/A            deallocateContextEvent[tid].
2422680Sktlim@umich.edu                reschedule(nextCycle(curTick + cycles(delay)));
2432462SN/A        else if (!deallocateContextEvent[tid].scheduled())
2442519SN/A            deallocateContextEvent[tid].
2452519SN/A                schedule(nextCycle(curTick + cycles(delay)));
2464434Ssaidi@eecs.umich.edu    }
2474434Ssaidi@eecs.umich.edu
2482519SN/A    /** Unschedule thread deallocation in CPU */
2492519SN/A    void unscheduleDeallocateContextEvent(int tid)
2501395SN/A    {
2512SN/A        if (deallocateContextEvent[tid].scheduled())
2522SN/A            deallocateContextEvent[tid].squash();
2532SN/A    }
2542SN/A
2552SN/A    /** The tick event used for scheduling CPU ticks. */
2562SN/A    DeallocateContextEvent deallocateContextEvent[Impl::MaxThreads];
2572SN/A
2582SN/A  public:
2595282Srstrong@cs.ucsd.edu    /** Constructs a CPU with the given parameters. */
2605282Srstrong@cs.ucsd.edu    FullO3CPU(O3CPU *o3_cpu, Params *params);
2612SN/A    /** Destructor. */
2622SN/A    ~FullO3CPU();
2632SN/A
2642SN/A    /** Registers statistics. */
2652SN/A    void fullCPURegStats();
2665282Srstrong@cs.ucsd.edu
2672SN/A    /** Returns a specific port. */
2682SN/A    Port *getPort(const std::string &if_name, int idx);
2692SN/A
2702SN/A    /** Ticks CPU, calling tick() on each stage, and checking the overall
2712SN/A     *  activity to see if the CPU should deschedule itself.
2722SN/A     */
2735282Srstrong@cs.ucsd.edu    void tick();
2745282Srstrong@cs.ucsd.edu
2755282Srstrong@cs.ucsd.edu    /** Initialize the CPU */
2765282Srstrong@cs.ucsd.edu    void init();
2775282Srstrong@cs.ucsd.edu
2785282Srstrong@cs.ucsd.edu    /** Returns the Number of Active Threads in the CPU */
2795282Srstrong@cs.ucsd.edu    int numActiveThreads()
2805282Srstrong@cs.ucsd.edu    { return activeThreads.size(); }
2815282Srstrong@cs.ucsd.edu
2825282Srstrong@cs.ucsd.edu    /** Add Thread to Active Threads List */
2831970SN/A    void activateThread(unsigned tid);
2841970SN/A
2852SN/A    /** Remove Thread from Active Threads List */
2862SN/A    void deactivateThread(unsigned tid);
2871970SN/A
2881970SN/A    /** Setup CPU to insert a thread's context */
2892SN/A    void insertThread(unsigned tid);
2901970SN/A
2911970SN/A    /** Remove all of a thread's context from CPU */
2921970SN/A    void removeThread(unsigned tid);
2931970SN/A
2941970SN/A    /** Count the Total Instructions Committed in the CPU. */
2955282Srstrong@cs.ucsd.edu    virtual Counter totalInstructions() const
2965282Srstrong@cs.ucsd.edu    {
2971970SN/A        Counter total(0);
2981970SN/A
2995282Srstrong@cs.ucsd.edu        for (int i=0; i < thread.size(); i++)
3005282Srstrong@cs.ucsd.edu            total += thread[i]->numInst;
3015282Srstrong@cs.ucsd.edu
3025282Srstrong@cs.ucsd.edu        return total;
3035282Srstrong@cs.ucsd.edu    }
3045282Srstrong@cs.ucsd.edu
3055282Srstrong@cs.ucsd.edu    /** Add Thread to Active Threads List. */
3062SN/A    void activateContext(int tid, int delay);
3072SN/A
3082SN/A    /** Remove Thread from Active Threads List */
3092SN/A    void suspendContext(int tid);
3102SN/A
3112SN/A    /** Remove Thread from Active Threads List &&
3122SN/A     *  Possibly Remove Thread Context from CPU.
3132SN/A     */
3142SN/A    bool deallocateContext(int tid, bool remove, int delay = 1);
3152SN/A
3165282Srstrong@cs.ucsd.edu    /** Remove Thread from Active Threads List &&
3172SN/A     *  Remove Thread Context from CPU.
3182SN/A     */
3195282Srstrong@cs.ucsd.edu    void haltContext(int tid);
3205282Srstrong@cs.ucsd.edu
3215282Srstrong@cs.ucsd.edu    /** Activate a Thread When CPU Resources are Available. */
3225282Srstrong@cs.ucsd.edu    void activateWhenReady(int tid);
3235282Srstrong@cs.ucsd.edu
3245282Srstrong@cs.ucsd.edu    /** Add or Remove a Thread Context in the CPU. */
3255282Srstrong@cs.ucsd.edu    void doContextSwitch();
3265282Srstrong@cs.ucsd.edu
3274434Ssaidi@eecs.umich.edu    /** Update The Order In Which We Process Threads. */
3284434Ssaidi@eecs.umich.edu    void updateThreadPriority();
3294434Ssaidi@eecs.umich.edu
3304434Ssaidi@eecs.umich.edu    /** Serialize state. */
3314434Ssaidi@eecs.umich.edu    virtual void serialize(std::ostream &os);
3324434Ssaidi@eecs.umich.edu
3334434Ssaidi@eecs.umich.edu    /** Unserialize from a checkpoint. */
3344434Ssaidi@eecs.umich.edu    virtual void unserialize(Checkpoint *cp, const std::string &section);
3354434Ssaidi@eecs.umich.edu
3364434Ssaidi@eecs.umich.edu  public:
3374434Ssaidi@eecs.umich.edu    /** Executes a syscall on this cycle.
3385154Sgblack@eecs.umich.edu     *  ---------------------------------------
3395154Sgblack@eecs.umich.edu     *  Note: this is a virtual function. CPU-Specific
3405154Sgblack@eecs.umich.edu     *  functionality defined in derived classes
3415154Sgblack@eecs.umich.edu     */
3425154Sgblack@eecs.umich.edu    virtual void syscall(int tid) { panic("Unimplemented!"); }
3435154Sgblack@eecs.umich.edu
3445154Sgblack@eecs.umich.edu    /** Starts draining the CPU's pipeline of all instructions in
3455154Sgblack@eecs.umich.edu     * order to stop all memory accesses. */
3465823Ssaidi@eecs.umich.edu    virtual unsigned int drain(Event *drain_event);
3475154Sgblack@eecs.umich.edu
3484434Ssaidi@eecs.umich.edu    /** Resumes execution after a drain. */
3494434Ssaidi@eecs.umich.edu    virtual void resume();
3504434Ssaidi@eecs.umich.edu
3514434Ssaidi@eecs.umich.edu    /** Signals to this CPU that a stage has completed switching out. */
3524434Ssaidi@eecs.umich.edu    void signalDrained();
3535282Srstrong@cs.ucsd.edu
3545282Srstrong@cs.ucsd.edu    /** Switches out this CPU. */
3555282Srstrong@cs.ucsd.edu    virtual void switchOut();
3565282Srstrong@cs.ucsd.edu
3575282Srstrong@cs.ucsd.edu    /** Takes over from another CPU. */
3585282Srstrong@cs.ucsd.edu    virtual void takeOverFrom(BaseCPU *oldCPU);
3595282Srstrong@cs.ucsd.edu
3605282Srstrong@cs.ucsd.edu    /** Get the current instruction sequence number, and increment it. */
3615514SMichael.Adler@intel.com    InstSeqNum getAndIncrementInstSeq()
3625282Srstrong@cs.ucsd.edu    { return globalSeqNum++; }
3635282Srstrong@cs.ucsd.edu
3645282Srstrong@cs.ucsd.edu#if FULL_SYSTEM
3655282Srstrong@cs.ucsd.edu    /** Update the Virt and Phys ports of all ThreadContexts to
3665282Srstrong@cs.ucsd.edu     * reflect change in memory connections. */
3675282Srstrong@cs.ucsd.edu    void updateMemPorts();
3685282Srstrong@cs.ucsd.edu
3695282Srstrong@cs.ucsd.edu    /** Check if this address is a valid instruction address. */
3705282Srstrong@cs.ucsd.edu    bool validInstAddr(Addr addr) { return true; }
3715282Srstrong@cs.ucsd.edu
3725282Srstrong@cs.ucsd.edu    /** Check if this address is a valid data address. */
3735282Srstrong@cs.ucsd.edu    bool validDataAddr(Addr addr) { return true; }
3745282Srstrong@cs.ucsd.edu
3755282Srstrong@cs.ucsd.edu    /** Get instruction asid. */
3765282Srstrong@cs.ucsd.edu    int getInstAsid(unsigned tid)
3775282Srstrong@cs.ucsd.edu    { return regFile.miscRegs[tid].getInstAsid(); }
3785282Srstrong@cs.ucsd.edu
3795282Srstrong@cs.ucsd.edu    /** Get data asid. */
3805282Srstrong@cs.ucsd.edu    int getDataAsid(unsigned tid)
3815282Srstrong@cs.ucsd.edu    { return regFile.miscRegs[tid].getDataAsid(); }
3825282Srstrong@cs.ucsd.edu#else
3835282Srstrong@cs.ucsd.edu    /** Get instruction asid. */
3845282Srstrong@cs.ucsd.edu    int getInstAsid(unsigned tid)
3855514SMichael.Adler@intel.com    { return thread[tid]->getInstAsid(); }
3865514SMichael.Adler@intel.com
3875282Srstrong@cs.ucsd.edu    /** Get data asid. */
3885282Srstrong@cs.ucsd.edu    int getDataAsid(unsigned tid)
3895514SMichael.Adler@intel.com    { return thread[tid]->getDataAsid(); }
3905514SMichael.Adler@intel.com
3915514SMichael.Adler@intel.com#endif
3925514SMichael.Adler@intel.com
3935514SMichael.Adler@intel.com    /** Register accessors.  Index refers to the physical register index. */
3945514SMichael.Adler@intel.com    uint64_t readIntReg(int reg_idx);
3955514SMichael.Adler@intel.com
3965514SMichael.Adler@intel.com    TheISA::FloatReg readFloatReg(int reg_idx);
3975514SMichael.Adler@intel.com
3985514SMichael.Adler@intel.com    TheISA::FloatReg readFloatReg(int reg_idx, int width);
3995514SMichael.Adler@intel.com
4005514SMichael.Adler@intel.com    TheISA::FloatRegBits readFloatRegBits(int reg_idx);
4015514SMichael.Adler@intel.com
4025282Srstrong@cs.ucsd.edu    TheISA::FloatRegBits readFloatRegBits(int reg_idx, int width);
4035282Srstrong@cs.ucsd.edu
4045282Srstrong@cs.ucsd.edu    void setIntReg(int reg_idx, uint64_t val);
4055282Srstrong@cs.ucsd.edu
4065282Srstrong@cs.ucsd.edu    void setFloatReg(int reg_idx, TheISA::FloatReg val);
4075282Srstrong@cs.ucsd.edu
4085282Srstrong@cs.ucsd.edu    void setFloatReg(int reg_idx, TheISA::FloatReg val, int width);
4095282Srstrong@cs.ucsd.edu
4105282Srstrong@cs.ucsd.edu    void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val);
4115282Srstrong@cs.ucsd.edu
4125282Srstrong@cs.ucsd.edu    void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val, int width);
4135282Srstrong@cs.ucsd.edu
4145282Srstrong@cs.ucsd.edu    uint64_t readArchIntReg(int reg_idx, unsigned tid);
4155282Srstrong@cs.ucsd.edu
4165282Srstrong@cs.ucsd.edu    float readArchFloatRegSingle(int reg_idx, unsigned tid);
4175282Srstrong@cs.ucsd.edu
4185282Srstrong@cs.ucsd.edu    double readArchFloatRegDouble(int reg_idx, unsigned tid);
4195282Srstrong@cs.ucsd.edu
4205282Srstrong@cs.ucsd.edu    uint64_t readArchFloatRegInt(int reg_idx, unsigned tid);
4215282Srstrong@cs.ucsd.edu
4225282Srstrong@cs.ucsd.edu    /** Architectural register accessors.  Looks up in the commit
4235282Srstrong@cs.ucsd.edu     * rename table to obtain the true physical index of the
4245282Srstrong@cs.ucsd.edu     * architected register first, then accesses that physical
4255282Srstrong@cs.ucsd.edu     * register.
4265282Srstrong@cs.ucsd.edu     */
4275282Srstrong@cs.ucsd.edu    void setArchIntReg(int reg_idx, uint64_t val, unsigned tid);
4285282Srstrong@cs.ucsd.edu
4295282Srstrong@cs.ucsd.edu    void setArchFloatRegSingle(int reg_idx, float val, unsigned tid);
4305282Srstrong@cs.ucsd.edu
4315282Srstrong@cs.ucsd.edu    void setArchFloatRegDouble(int reg_idx, double val, unsigned tid);
4325282Srstrong@cs.ucsd.edu
4335282Srstrong@cs.ucsd.edu    void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid);
4345282Srstrong@cs.ucsd.edu
4355282Srstrong@cs.ucsd.edu    /** Reads the commit PC of a specific thread. */
4365282Srstrong@cs.ucsd.edu    uint64_t readPC(unsigned tid);
4375282Srstrong@cs.ucsd.edu
4385282Srstrong@cs.ucsd.edu    /** Sets the commit PC of a specific thread. */
4395282Srstrong@cs.ucsd.edu    void setPC(Addr new_PC, unsigned tid);
4405282Srstrong@cs.ucsd.edu
4415282Srstrong@cs.ucsd.edu    /** Reads the next PC of a specific thread. */
4425282Srstrong@cs.ucsd.edu    uint64_t readNextPC(unsigned tid);
4435282Srstrong@cs.ucsd.edu
4445282Srstrong@cs.ucsd.edu    /** Sets the next PC of a specific thread. */
4455282Srstrong@cs.ucsd.edu    void setNextPC(uint64_t val, unsigned tid);
4465282Srstrong@cs.ucsd.edu
4475282Srstrong@cs.ucsd.edu    /** Reads the next NPC of a specific thread. */
4485282Srstrong@cs.ucsd.edu    uint64_t readNextNPC(unsigned tid);
4495282Srstrong@cs.ucsd.edu
4505282Srstrong@cs.ucsd.edu    /** Sets the next NPC of a specific thread. */
4515282Srstrong@cs.ucsd.edu    void setNextNPC(uint64_t val, unsigned tid);
4525282Srstrong@cs.ucsd.edu
4535282Srstrong@cs.ucsd.edu    /** Function to add instruction onto the head of the list of the
4545282Srstrong@cs.ucsd.edu     *  instructions.  Used when new instructions are fetched.
4555282Srstrong@cs.ucsd.edu     */
4565282Srstrong@cs.ucsd.edu    ListIt addInst(DynInstPtr &inst);
4575282Srstrong@cs.ucsd.edu
4585282Srstrong@cs.ucsd.edu    /** Function to tell the CPU that an instruction has completed. */
4595282Srstrong@cs.ucsd.edu    void instDone(unsigned tid);
4605282Srstrong@cs.ucsd.edu
4615282Srstrong@cs.ucsd.edu    /** Add Instructions to the CPU Remove List*/
4625282Srstrong@cs.ucsd.edu    void addToRemoveList(DynInstPtr &inst);
4635282Srstrong@cs.ucsd.edu
4645282Srstrong@cs.ucsd.edu    /** Remove an instruction from the front end of the list.  There's
4655282Srstrong@cs.ucsd.edu     *  no restriction on location of the instruction.
4665282Srstrong@cs.ucsd.edu     */
4675282Srstrong@cs.ucsd.edu    void removeFrontInst(DynInstPtr &inst);
4685282Srstrong@cs.ucsd.edu
4695282Srstrong@cs.ucsd.edu    /** Remove all instructions that are not currently in the ROB.
4705282Srstrong@cs.ucsd.edu     *  There's also an option to not squash delay slot instructions.*/
4715282Srstrong@cs.ucsd.edu    void removeInstsNotInROB(unsigned tid);
4725282Srstrong@cs.ucsd.edu
4735282Srstrong@cs.ucsd.edu    /** Remove all instructions younger than the given sequence number. */
4745282Srstrong@cs.ucsd.edu    void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
4755282Srstrong@cs.ucsd.edu
4765282Srstrong@cs.ucsd.edu    /** Removes the instruction pointed to by the iterator. */
4775282Srstrong@cs.ucsd.edu    inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
4785282Srstrong@cs.ucsd.edu
4795282Srstrong@cs.ucsd.edu    /** Cleans up all instructions on the remove list. */
4805282Srstrong@cs.ucsd.edu    void cleanUpRemovedInsts();
4815282Srstrong@cs.ucsd.edu
4825282Srstrong@cs.ucsd.edu    /** Debug function to print all instructions on the list. */
4835282Srstrong@cs.ucsd.edu    void dumpInsts();
4845282Srstrong@cs.ucsd.edu
4855282Srstrong@cs.ucsd.edu  public:
4865282Srstrong@cs.ucsd.edu    /** List of all the instructions in flight. */
4873311Ssaidi@eecs.umich.edu    std::list<DynInstPtr> instList;
4883311Ssaidi@eecs.umich.edu
4893311Ssaidi@eecs.umich.edu    /** List of all the instructions that will be removed at the end of this
4903311Ssaidi@eecs.umich.edu     *  cycle.
4913311Ssaidi@eecs.umich.edu     */
4923311Ssaidi@eecs.umich.edu    std::queue<ListIt> removeList;
4933311Ssaidi@eecs.umich.edu
4943311Ssaidi@eecs.umich.edu#ifdef DEBUG
4953311Ssaidi@eecs.umich.edu    /** Debug structure to keep track of the sequence numbers still in
4963311Ssaidi@eecs.umich.edu     * flight.
4973311Ssaidi@eecs.umich.edu     */
4983311Ssaidi@eecs.umich.edu    std::set<InstSeqNum> snList;
4993311Ssaidi@eecs.umich.edu#endif
5005282Srstrong@cs.ucsd.edu
5015282Srstrong@cs.ucsd.edu    /** Records if instructions need to be removed this cycle due to
5025282Srstrong@cs.ucsd.edu     *  being retired or squashed.
5035282Srstrong@cs.ucsd.edu     */
5045282Srstrong@cs.ucsd.edu    bool removeInstsThisCycle;
5055282Srstrong@cs.ucsd.edu
5063311Ssaidi@eecs.umich.edu  protected:
5073311Ssaidi@eecs.umich.edu    /** The fetch stage. */
5083311Ssaidi@eecs.umich.edu    typename CPUPolicy::Fetch fetch;
5093311Ssaidi@eecs.umich.edu
5103311Ssaidi@eecs.umich.edu    /** The decode stage. */
5113311Ssaidi@eecs.umich.edu    typename CPUPolicy::Decode decode;
5123311Ssaidi@eecs.umich.edu
5133311Ssaidi@eecs.umich.edu    /** The dispatch stage. */
5143311Ssaidi@eecs.umich.edu    typename CPUPolicy::Rename rename;
5153311Ssaidi@eecs.umich.edu
5163311Ssaidi@eecs.umich.edu    /** The issue/execute/writeback stages. */
5173311Ssaidi@eecs.umich.edu    typename CPUPolicy::IEW iew;
5183311Ssaidi@eecs.umich.edu
5193311Ssaidi@eecs.umich.edu    /** The commit stage. */
5203311Ssaidi@eecs.umich.edu    typename CPUPolicy::Commit commit;
5213311Ssaidi@eecs.umich.edu
5223311Ssaidi@eecs.umich.edu    /** The register file. */
5235282Srstrong@cs.ucsd.edu    typename CPUPolicy::RegFile regFile;
5245282Srstrong@cs.ucsd.edu
5255282Srstrong@cs.ucsd.edu    /** The free list. */
5265282Srstrong@cs.ucsd.edu    typename CPUPolicy::FreeList freeList;
5275183Ssaidi@eecs.umich.edu
5285183Ssaidi@eecs.umich.edu    /** The rename map. */
5295183Ssaidi@eecs.umich.edu    typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads];
5303311Ssaidi@eecs.umich.edu
5312SN/A    /** The commit rename map. */
5322SN/A    typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads];
5332SN/A
5342SN/A    /** The re-order buffer. */
5352SN/A    typename CPUPolicy::ROB rob;
5362SN/A
5372SN/A    /** Active Threads List */
5382SN/A    std::list<unsigned> activeThreads;
53912SN/A
5405154Sgblack@eecs.umich.edu    /** Integer Register Scoreboard */
5415154Sgblack@eecs.umich.edu    Scoreboard scoreboard;
5425154Sgblack@eecs.umich.edu
5432SN/A  public:
5445154Sgblack@eecs.umich.edu    /** Enum to give each stage a specific index, so when calling
5455154Sgblack@eecs.umich.edu     *  activateStage() or deactivateStage(), they can specify which stage
5465154Sgblack@eecs.umich.edu     *  is being activated/deactivated.
5475154Sgblack@eecs.umich.edu     */
5485154Sgblack@eecs.umich.edu    enum StageIdx {
5495154Sgblack@eecs.umich.edu        FetchIdx,
5503114Sgblack@eecs.umich.edu        DecodeIdx,
5515154Sgblack@eecs.umich.edu        RenameIdx,
55212SN/A        IEWIdx,
5531158SN/A        CommitIdx,
5541158SN/A        NumStages };
5551158SN/A
5561158SN/A    /** Typedefs from the Impl to get the structs that each of the
5571158SN/A     *  time buffers should use.
5581158SN/A     */
5591158SN/A    typedef typename CPUPolicy::TimeStruct TimeStruct;
5601158SN/A
5611158SN/A    typedef typename CPUPolicy::FetchStruct FetchStruct;
5621158SN/A
5631158SN/A    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
5642378SN/A
5651158SN/A    typedef typename CPUPolicy::RenameStruct RenameStruct;
5662378SN/A
5672474SN/A    typedef typename CPUPolicy::IEWStruct IEWStruct;
5682378SN/A
5692378SN/A    /** The main time buffer to do backwards communication. */
57012SN/A    TimeBuffer<TimeStruct> timeBuffer;
5712378SN/A
5722378SN/A    /** The fetch stage's instruction queue. */
57312SN/A    TimeBuffer<FetchStruct> fetchQueue;
57412SN/A
5752474SN/A    /** The decode stage's instruction queue. */
5762474SN/A    TimeBuffer<DecodeStruct> decodeQueue;
57712SN/A
57812SN/A    /** The rename stage's instruction queue. */
57912SN/A    TimeBuffer<RenameStruct> renameQueue;
58012SN/A
58112SN/A    /** The IEW stage's instruction queue. */
58212SN/A    TimeBuffer<IEWStruct> iewQueue;
58312SN/A
58412SN/A  private:
58512SN/A    /** The activity recorder; used to tell if the CPU has any
58612SN/A     * activity remaining or if it can go to idle and deschedule
58712SN/A     * itself.
5883005Sstever@eecs.umich.edu     */
5893005Sstever@eecs.umich.edu    ActivityRecorder activityRec;
59012SN/A
59112SN/A  public:
59212SN/A    /** Records that there was time buffer activity this cycle. */
59312SN/A    void activityThisCycle() { activityRec.activity(); }
5942800Ssaidi@eecs.umich.edu
59512SN/A    /** Changes a stage's status to active within the activity recorder. */
5962378SN/A    void activateStage(const StageIdx idx)
5972800Ssaidi@eecs.umich.edu    { activityRec.activateStage(idx); }
59812SN/A
59912SN/A    /** Changes a stage's status to inactive within the activity recorder. */
6002523SN/A    void deactivateStage(const StageIdx idx)
60112SN/A    { activityRec.deactivateStage(idx); }
60212SN/A
60312SN/A    /** Wakes the CPU, rescheduling the CPU if it's not already active. */
60412SN/A    void wakeCPU();
60512SN/A
60612SN/A    /** Gets a free thread id. Use if thread ids change across system. */
6072474SN/A    int getFreeTid();
6082474SN/A
6092474SN/A  public:
6102474SN/A    /** Returns a pointer to a thread context. */
6112474SN/A    ThreadContext *tcBase(unsigned tid)
6122474SN/A    {
6132474SN/A        return thread[tid]->getTC();
6142474SN/A    }
61512SN/A
6162378SN/A    /** The global sequence number counter. */
6172378SN/A    InstSeqNum globalSeqNum;//[Impl::MaxThreads];
61812SN/A
6194772Sgblack@eecs.umich.edu    /** Pointer to the checker, which can dynamically verify
6205713Shsul@eecs.umich.edu     * instruction results at run time.  This can be set to NULL if it
6215713Shsul@eecs.umich.edu     * is not being used.
6225713Shsul@eecs.umich.edu     */
6235713Shsul@eecs.umich.edu    Checker<DynInstPtr> *checker;
6245713Shsul@eecs.umich.edu
6255713Shsul@eecs.umich.edu#if FULL_SYSTEM
6262451SN/A    /** Pointer to the system. */
6272451SN/A    System *system;
6285713Shsul@eecs.umich.edu
6295713Shsul@eecs.umich.edu    /** Pointer to physical memory. */
6302817Sksewell@umich.edu    PhysicalMemory *physmem;
6312817Sksewell@umich.edu#endif
6325713Shsul@eecs.umich.edu
6332817Sksewell@umich.edu    /** Event to call process() on once draining has completed. */
6342378SN/A    Event *drainEvent;
6352378SN/A
6362SN/A    /** Counter of how many stages have completed draining. */
6372SN/A    int drainCount;
6382093SN/A
6392680Sktlim@umich.edu    /** Pointers to all of the threads in the CPU. */
6402093SN/A    std::vector<Thread *> thread;
6412093SN/A
6422093SN/A    /** Whether or not the CPU should defer its registration. */
6432093SN/A    bool deferRegistration;
6442093SN/A
6452093SN/A    /** Is there a context switch pending? */
6462093SN/A    bool contextSwitch;
6472680Sktlim@umich.edu
6482093SN/A    /** Threads Scheduled to Enter CPU */
6492SN/A    std::list<int> cpuWaitList;
6502715Sstever@eecs.umich.edu
6515154Sgblack@eecs.umich.edu    /** The cycle that the CPU was last running, used for statistics. */
6522715Sstever@eecs.umich.edu    Tick lastRunningCycle;
6532715Sstever@eecs.umich.edu
6542715Sstever@eecs.umich.edu    /** The cycle that the CPU was last activated by a new thread*/
6555154Sgblack@eecs.umich.edu    Tick lastActivatedCycle;
6565154Sgblack@eecs.umich.edu
6572715Sstever@eecs.umich.edu    /** Number of Threads CPU can process */
6582715Sstever@eecs.umich.edu    unsigned numThreads;
6592715Sstever@eecs.umich.edu
6602715Sstever@eecs.umich.edu    /** Mapping for system thread id to cpu id */
6612715Sstever@eecs.umich.edu    std::map<unsigned,unsigned> threadMap;
6623917Ssaidi@eecs.umich.edu
6633917Ssaidi@eecs.umich.edu    /** Available thread ids in the cpu*/
6645070Ssaidi@eecs.umich.edu    std::vector<unsigned> tids;
6653917Ssaidi@eecs.umich.edu
6663917Ssaidi@eecs.umich.edu    /** Stat for total number of times the CPU is descheduled. */
6675089Sgblack@eecs.umich.edu    Stats::Scalar<> timesIdled;
6685753Ssteve.reinhardt@amd.com    /** Stat for total number of cycles the CPU spends descheduled. */
6695753Ssteve.reinhardt@amd.com    Stats::Scalar<> idleCycles;
6705753Ssteve.reinhardt@amd.com    /** Stat for the number of committed instructions per thread. */
6712715Sstever@eecs.umich.edu    Stats::Vector<> committedInsts;
6722715Sstever@eecs.umich.edu    /** Stat for the total number of committed instructions. */
6735154Sgblack@eecs.umich.edu    Stats::Scalar<> totalCommittedInsts;
6742715Sstever@eecs.umich.edu    /** Stat for the CPI per thread. */
6752715Sstever@eecs.umich.edu    Stats::Formula cpi;
6765753Ssteve.reinhardt@amd.com    /** Stat for the total CPI. */
6775753Ssteve.reinhardt@amd.com    Stats::Formula totalCpi;
6785753Ssteve.reinhardt@amd.com    /** Stat for the IPC per thread. */
6792715Sstever@eecs.umich.edu    Stats::Formula ipc;
6805154Sgblack@eecs.umich.edu    /** Stat for the total IPC. */
6812715Sstever@eecs.umich.edu    Stats::Formula totalIpc;
6822715Sstever@eecs.umich.edu};
6832715Sstever@eecs.umich.edu
6842715Sstever@eecs.umich.edu#endif // __CPU_O3_CPU_HH__
6852715Sstever@eecs.umich.edu