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 §ion); 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