cpu.hh revision 5529
18541Sgblack@eecs.umich.edu/*
28541Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
38541Sgblack@eecs.umich.edu * All rights reserved.
48541Sgblack@eecs.umich.edu *
58541Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
68541Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
78541Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
88541Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
98541Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
108541Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
118541Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
128541Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
138541Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
148541Sgblack@eecs.umich.edu * this software without specific prior written permission.
158541Sgblack@eecs.umich.edu *
168541Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178541Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188541Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198541Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208541Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218541Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228541Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238541Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248541Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258541Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
268541Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278541Sgblack@eecs.umich.edu *
288541Sgblack@eecs.umich.edu * Authors: Kevin Lim
298541Sgblack@eecs.umich.edu *          Korey Sewell
308541Sgblack@eecs.umich.edu */
318541Sgblack@eecs.umich.edu
328541Sgblack@eecs.umich.edu#ifndef __CPU_O3_CPU_HH__
338541Sgblack@eecs.umich.edu#define __CPU_O3_CPU_HH__
348541Sgblack@eecs.umich.edu
358541Sgblack@eecs.umich.edu#include <iostream>
368541Sgblack@eecs.umich.edu#include <list>
378541Sgblack@eecs.umich.edu#include <queue>
388541Sgblack@eecs.umich.edu#include <set>
398541Sgblack@eecs.umich.edu#include <vector>
408541Sgblack@eecs.umich.edu
418541Sgblack@eecs.umich.edu#include "arch/types.hh"
428541Sgblack@eecs.umich.edu#include "base/statistics.hh"
438541Sgblack@eecs.umich.edu#include "base/timebuf.hh"
448541Sgblack@eecs.umich.edu#include "config/full_system.hh"
458541Sgblack@eecs.umich.edu#include "config/use_checker.hh"
468541Sgblack@eecs.umich.edu#include "cpu/activity.hh"
478541Sgblack@eecs.umich.edu#include "cpu/base.hh"
488541Sgblack@eecs.umich.edu#include "cpu/simple_thread.hh"
498541Sgblack@eecs.umich.edu#include "cpu/o3/comm.hh"
508541Sgblack@eecs.umich.edu#include "cpu/o3/cpu_policy.hh"
519021Sgblack@eecs.umich.edu#include "cpu/o3/scoreboard.hh"
529021Sgblack@eecs.umich.edu#include "cpu/o3/thread_state.hh"
538541Sgblack@eecs.umich.edu//#include "cpu/o3/thread_context.hh"
548541Sgblack@eecs.umich.edu#include "sim/process.hh"
558541Sgblack@eecs.umich.edu
568541Sgblack@eecs.umich.edu#include "params/DerivO3CPU.hh"
578541Sgblack@eecs.umich.edu
588541Sgblack@eecs.umich.edutemplate <class>
598541Sgblack@eecs.umich.educlass Checker;
608541Sgblack@eecs.umich.educlass ThreadContext;
618541Sgblack@eecs.umich.edutemplate <class>
628541Sgblack@eecs.umich.educlass O3ThreadContext;
638541Sgblack@eecs.umich.edu
648541Sgblack@eecs.umich.educlass Checkpoint;
658541Sgblack@eecs.umich.educlass MemObject;
668541Sgblack@eecs.umich.educlass Process;
678541Sgblack@eecs.umich.edu
688541Sgblack@eecs.umich.educlass BaseCPUParams;
698541Sgblack@eecs.umich.edu
708541Sgblack@eecs.umich.educlass BaseO3CPU : public BaseCPU
718541Sgblack@eecs.umich.edu{
728541Sgblack@eecs.umich.edu    //Stuff that's pretty ISA independent will go here.
739021Sgblack@eecs.umich.edu  public:
749021Sgblack@eecs.umich.edu    BaseO3CPU(BaseCPUParams *params);
759021Sgblack@eecs.umich.edu
769021Sgblack@eecs.umich.edu    void regStats();
779021Sgblack@eecs.umich.edu
789021Sgblack@eecs.umich.edu    /** Sets this CPU's ID. */
799021Sgblack@eecs.umich.edu    void setCpuId(int id) { cpu_id = id; }
809021Sgblack@eecs.umich.edu
818541Sgblack@eecs.umich.edu    /** Reads this CPU's ID. */
828541Sgblack@eecs.umich.edu    int readCpuId() { return cpu_id; }
838541Sgblack@eecs.umich.edu
848541Sgblack@eecs.umich.edu  protected:
858541Sgblack@eecs.umich.edu    int cpu_id;
868541Sgblack@eecs.umich.edu};
878541Sgblack@eecs.umich.edu
888541Sgblack@eecs.umich.edu/**
898541Sgblack@eecs.umich.edu * FullO3CPU class, has each of the stages (fetch through commit)
908541Sgblack@eecs.umich.edu * within it, as well as all of the time buffers between stages.  The
918541Sgblack@eecs.umich.edu * tick() function for the CPU is defined here.
928541Sgblack@eecs.umich.edu */
939021Sgblack@eecs.umich.edutemplate <class Impl>
948541Sgblack@eecs.umich.educlass FullO3CPU : public BaseO3CPU
958541Sgblack@eecs.umich.edu{
968541Sgblack@eecs.umich.edu  public:
978541Sgblack@eecs.umich.edu    // Typedefs from the Impl here.
988541Sgblack@eecs.umich.edu    typedef typename Impl::CPUPol CPUPolicy;
998541Sgblack@eecs.umich.edu    typedef typename Impl::DynInstPtr DynInstPtr;
1008541Sgblack@eecs.umich.edu    typedef typename Impl::O3CPU O3CPU;
1018541Sgblack@eecs.umich.edu
1028541Sgblack@eecs.umich.edu    typedef O3ThreadState<Impl> Thread;
1038541Sgblack@eecs.umich.edu
1048541Sgblack@eecs.umich.edu    typedef typename std::list<DynInstPtr>::iterator ListIt;
1058541Sgblack@eecs.umich.edu
1068541Sgblack@eecs.umich.edu    friend class O3ThreadContext<Impl>;
1078541Sgblack@eecs.umich.edu
1088541Sgblack@eecs.umich.edu  public:
1098541Sgblack@eecs.umich.edu    enum Status {
1108541Sgblack@eecs.umich.edu        Running,
1118541Sgblack@eecs.umich.edu        Idle,
1128541Sgblack@eecs.umich.edu        Halted,
1138541Sgblack@eecs.umich.edu        Blocked,
1148541Sgblack@eecs.umich.edu        SwitchedOut
1158541Sgblack@eecs.umich.edu    };
1169021Sgblack@eecs.umich.edu
1179021Sgblack@eecs.umich.edu    TheISA::ITB * itb;
1189021Sgblack@eecs.umich.edu    TheISA::DTB * dtb;
1199021Sgblack@eecs.umich.edu
1208541Sgblack@eecs.umich.edu    /** Overall CPU status. */
1218541Sgblack@eecs.umich.edu    Status _status;
1228541Sgblack@eecs.umich.edu
1238541Sgblack@eecs.umich.edu    /** Per-thread status in CPU, used for SMT.  */
1248541Sgblack@eecs.umich.edu    Status _threadStatus[Impl::MaxThreads];
1258541Sgblack@eecs.umich.edu
1268541Sgblack@eecs.umich.edu  private:
1278541Sgblack@eecs.umich.edu    class TickEvent : public Event
1288541Sgblack@eecs.umich.edu    {
1298541Sgblack@eecs.umich.edu      private:
1308541Sgblack@eecs.umich.edu        /** Pointer to the CPU. */
1319021Sgblack@eecs.umich.edu        FullO3CPU<Impl> *cpu;
1328541Sgblack@eecs.umich.edu
1338541Sgblack@eecs.umich.edu      public:
1348541Sgblack@eecs.umich.edu        /** Constructs a tick event. */
1359021Sgblack@eecs.umich.edu        TickEvent(FullO3CPU<Impl> *c);
1369021Sgblack@eecs.umich.edu
1379021Sgblack@eecs.umich.edu        /** Processes a tick event, calling tick() on the CPU. */
1389021Sgblack@eecs.umich.edu        void process();
1399021Sgblack@eecs.umich.edu        /** Returns the description of the tick event. */
1409021Sgblack@eecs.umich.edu        const char *description() const;
1419021Sgblack@eecs.umich.edu    };
1429021Sgblack@eecs.umich.edu
1439021Sgblack@eecs.umich.edu    /** The tick event used for scheduling CPU ticks. */
1449021Sgblack@eecs.umich.edu    TickEvent tickEvent;
1459021Sgblack@eecs.umich.edu
1469021Sgblack@eecs.umich.edu    /** Schedule tick event, regardless of its current state. */
1479021Sgblack@eecs.umich.edu    void scheduleTickEvent(int delay)
1489021Sgblack@eecs.umich.edu    {
1499021Sgblack@eecs.umich.edu        if (tickEvent.squashed())
1509021Sgblack@eecs.umich.edu            tickEvent.reschedule(nextCycle(curTick + ticks(delay)));
1518541Sgblack@eecs.umich.edu        else if (!tickEvent.scheduled())
1528541Sgblack@eecs.umich.edu            tickEvent.schedule(nextCycle(curTick + ticks(delay)));
1538541Sgblack@eecs.umich.edu    }
1548541Sgblack@eecs.umich.edu
155    /** Unschedule tick event, regardless of its current state. */
156    void unscheduleTickEvent()
157    {
158        if (tickEvent.scheduled())
159            tickEvent.squash();
160    }
161
162    class ActivateThreadEvent : public Event
163    {
164      private:
165        /** Number of Thread to Activate */
166        int tid;
167
168        /** Pointer to the CPU. */
169        FullO3CPU<Impl> *cpu;
170
171      public:
172        /** Constructs the event. */
173        ActivateThreadEvent();
174
175        /** Initialize Event */
176        void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
177
178        /** Processes the event, calling activateThread() on the CPU. */
179        void process();
180
181        /** Returns the description of the event. */
182        const char *description() const;
183    };
184
185    /** Schedule thread to activate , regardless of its current state. */
186    void scheduleActivateThreadEvent(int tid, int delay)
187    {
188        // Schedule thread to activate, regardless of its current state.
189        if (activateThreadEvent[tid].squashed())
190            activateThreadEvent[tid].
191                reschedule(nextCycle(curTick + ticks(delay)));
192        else if (!activateThreadEvent[tid].scheduled())
193            activateThreadEvent[tid].
194                schedule(nextCycle(curTick + ticks(delay)));
195    }
196
197    /** Unschedule actiavte thread event, regardless of its current state. */
198    void unscheduleActivateThreadEvent(int tid)
199    {
200        if (activateThreadEvent[tid].scheduled())
201            activateThreadEvent[tid].squash();
202    }
203
204    /** The tick event used for scheduling CPU ticks. */
205    ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
206
207    class DeallocateContextEvent : public Event
208    {
209      private:
210        /** Number of Thread to deactivate */
211        int tid;
212
213        /** Should the thread be removed from the CPU? */
214        bool remove;
215
216        /** Pointer to the CPU. */
217        FullO3CPU<Impl> *cpu;
218
219      public:
220        /** Constructs the event. */
221        DeallocateContextEvent();
222
223        /** Initialize Event */
224        void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
225
226        /** Processes the event, calling activateThread() on the CPU. */
227        void process();
228
229        /** Sets whether the thread should also be removed from the CPU. */
230        void setRemove(bool _remove) { remove = _remove; }
231
232        /** Returns the description of the event. */
233        const char *description() const;
234    };
235
236    /** Schedule cpu to deallocate thread context.*/
237    void scheduleDeallocateContextEvent(int tid, bool remove, int delay)
238    {
239        // Schedule thread to activate, regardless of its current state.
240        if (deallocateContextEvent[tid].squashed())
241            deallocateContextEvent[tid].
242                reschedule(nextCycle(curTick + ticks(delay)));
243        else if (!deallocateContextEvent[tid].scheduled())
244            deallocateContextEvent[tid].
245                schedule(nextCycle(curTick + ticks(delay)));
246    }
247
248    /** Unschedule thread deallocation in CPU */
249    void unscheduleDeallocateContextEvent(int tid)
250    {
251        if (deallocateContextEvent[tid].scheduled())
252            deallocateContextEvent[tid].squash();
253    }
254
255    /** The tick event used for scheduling CPU ticks. */
256    DeallocateContextEvent deallocateContextEvent[Impl::MaxThreads];
257
258  public:
259    /** Constructs a CPU with the given parameters. */
260    FullO3CPU(O3CPU *o3_cpu, DerivO3CPUParams *params);
261    /** Destructor. */
262    ~FullO3CPU();
263
264    /** Registers statistics. */
265    void fullCPURegStats();
266
267    void demapPage(Addr vaddr, uint64_t asn)
268    {
269        this->itb->demapPage(vaddr, asn);
270        this->dtb->demapPage(vaddr, asn);
271    }
272
273    void demapInstPage(Addr vaddr, uint64_t asn)
274    {
275        this->itb->demapPage(vaddr, asn);
276    }
277
278    void demapDataPage(Addr vaddr, uint64_t asn)
279    {
280        this->dtb->demapPage(vaddr, asn);
281    }
282
283    /** Translates instruction requestion. */
284    Fault translateInstReq(RequestPtr &req, Thread *thread)
285    {
286        return this->itb->translate(req, thread->getTC());
287    }
288
289    /** Translates data read request. */
290    Fault translateDataReadReq(RequestPtr &req, Thread *thread)
291    {
292        return this->dtb->translate(req, thread->getTC(), false);
293    }
294
295    /** Translates data write request. */
296    Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
297    {
298        return this->dtb->translate(req, thread->getTC(), true);
299    }
300
301    /** Returns a specific port. */
302    Port *getPort(const std::string &if_name, int idx);
303
304    /** Ticks CPU, calling tick() on each stage, and checking the overall
305     *  activity to see if the CPU should deschedule itself.
306     */
307    void tick();
308
309    /** Initialize the CPU */
310    void init();
311
312    /** Returns the Number of Active Threads in the CPU */
313    int numActiveThreads()
314    { return activeThreads.size(); }
315
316    /** Add Thread to Active Threads List */
317    void activateThread(unsigned tid);
318
319    /** Remove Thread from Active Threads List */
320    void deactivateThread(unsigned tid);
321
322    /** Setup CPU to insert a thread's context */
323    void insertThread(unsigned tid);
324
325    /** Remove all of a thread's context from CPU */
326    void removeThread(unsigned tid);
327
328    /** Count the Total Instructions Committed in the CPU. */
329    virtual Counter totalInstructions() const
330    {
331        Counter total(0);
332
333        for (int i=0; i < thread.size(); i++)
334            total += thread[i]->numInst;
335
336        return total;
337    }
338
339    /** Add Thread to Active Threads List. */
340    void activateContext(int tid, int delay);
341
342    /** Remove Thread from Active Threads List */
343    void suspendContext(int tid);
344
345    /** Remove Thread from Active Threads List &&
346     *  Possibly Remove Thread Context from CPU.
347     */
348    bool deallocateContext(int tid, bool remove, int delay = 1);
349
350    /** Remove Thread from Active Threads List &&
351     *  Remove Thread Context from CPU.
352     */
353    void haltContext(int tid);
354
355    /** Activate a Thread When CPU Resources are Available. */
356    void activateWhenReady(int tid);
357
358    /** Add or Remove a Thread Context in the CPU. */
359    void doContextSwitch();
360
361    /** Update The Order In Which We Process Threads. */
362    void updateThreadPriority();
363
364    /** Serialize state. */
365    virtual void serialize(std::ostream &os);
366
367    /** Unserialize from a checkpoint. */
368    virtual void unserialize(Checkpoint *cp, const std::string &section);
369
370  public:
371    /** Executes a syscall on this cycle.
372     *  ---------------------------------------
373     *  Note: this is a virtual function. CPU-Specific
374     *  functionality defined in derived classes
375     */
376    virtual void syscall(int tid) { panic("Unimplemented!"); }
377
378    /** Starts draining the CPU's pipeline of all instructions in
379     * order to stop all memory accesses. */
380    virtual unsigned int drain(Event *drain_event);
381
382    /** Resumes execution after a drain. */
383    virtual void resume();
384
385    /** Signals to this CPU that a stage has completed switching out. */
386    void signalDrained();
387
388    /** Switches out this CPU. */
389    virtual void switchOut();
390
391    /** Takes over from another CPU. */
392    virtual void takeOverFrom(BaseCPU *oldCPU);
393
394    /** Get the current instruction sequence number, and increment it. */
395    InstSeqNum getAndIncrementInstSeq()
396    { return globalSeqNum++; }
397
398#if FULL_SYSTEM
399    /** Update the Virt and Phys ports of all ThreadContexts to
400     * reflect change in memory connections. */
401    void updateMemPorts();
402
403    /** Check if this address is a valid instruction address. */
404    bool validInstAddr(Addr addr) { return true; }
405
406    /** Check if this address is a valid data address. */
407    bool validDataAddr(Addr addr) { return true; }
408
409    /** Get instruction asid. */
410    int getInstAsid(unsigned tid)
411    { return regFile.miscRegs[tid].getInstAsid(); }
412
413    /** Get data asid. */
414    int getDataAsid(unsigned tid)
415    { return regFile.miscRegs[tid].getDataAsid(); }
416#else
417    /** Get instruction asid. */
418    int getInstAsid(unsigned tid)
419    { return thread[tid]->getInstAsid(); }
420
421    /** Get data asid. */
422    int getDataAsid(unsigned tid)
423    { return thread[tid]->getDataAsid(); }
424
425#endif
426
427    /** Register accessors.  Index refers to the physical register index. */
428    uint64_t readIntReg(int reg_idx);
429
430    TheISA::FloatReg readFloatReg(int reg_idx);
431
432    TheISA::FloatReg readFloatReg(int reg_idx, int width);
433
434    TheISA::FloatRegBits readFloatRegBits(int reg_idx);
435
436    TheISA::FloatRegBits readFloatRegBits(int reg_idx, int width);
437
438    void setIntReg(int reg_idx, uint64_t val);
439
440    void setFloatReg(int reg_idx, TheISA::FloatReg val);
441
442    void setFloatReg(int reg_idx, TheISA::FloatReg val, int width);
443
444    void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val);
445
446    void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val, int width);
447
448    uint64_t readArchIntReg(int reg_idx, unsigned tid);
449
450    float readArchFloatRegSingle(int reg_idx, unsigned tid);
451
452    double readArchFloatRegDouble(int reg_idx, unsigned tid);
453
454    uint64_t readArchFloatRegInt(int reg_idx, unsigned tid);
455
456    /** Architectural register accessors.  Looks up in the commit
457     * rename table to obtain the true physical index of the
458     * architected register first, then accesses that physical
459     * register.
460     */
461    void setArchIntReg(int reg_idx, uint64_t val, unsigned tid);
462
463    void setArchFloatRegSingle(int reg_idx, float val, unsigned tid);
464
465    void setArchFloatRegDouble(int reg_idx, double val, unsigned tid);
466
467    void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid);
468
469    /** Reads the commit PC of a specific thread. */
470    Addr readPC(unsigned tid);
471
472    /** Sets the commit PC of a specific thread. */
473    void setPC(Addr new_PC, unsigned tid);
474
475    /** Reads the commit micro PC of a specific thread. */
476    Addr readMicroPC(unsigned tid);
477
478    /** Sets the commmit micro PC of a specific thread. */
479    void setMicroPC(Addr new_microPC, unsigned tid);
480
481    /** Reads the next PC of a specific thread. */
482    Addr readNextPC(unsigned tid);
483
484    /** Sets the next PC of a specific thread. */
485    void setNextPC(Addr val, unsigned tid);
486
487    /** Reads the next NPC of a specific thread. */
488    Addr readNextNPC(unsigned tid);
489
490    /** Sets the next NPC of a specific thread. */
491    void setNextNPC(Addr val, unsigned tid);
492
493    /** Reads the commit next micro PC of a specific thread. */
494    Addr readNextMicroPC(unsigned tid);
495
496    /** Sets the commit next micro PC of a specific thread. */
497    void setNextMicroPC(Addr val, unsigned tid);
498
499    /** Function to add instruction onto the head of the list of the
500     *  instructions.  Used when new instructions are fetched.
501     */
502    ListIt addInst(DynInstPtr &inst);
503
504    /** Function to tell the CPU that an instruction has completed. */
505    void instDone(unsigned tid);
506
507    /** Add Instructions to the CPU Remove List*/
508    void addToRemoveList(DynInstPtr &inst);
509
510    /** Remove an instruction from the front end of the list.  There's
511     *  no restriction on location of the instruction.
512     */
513    void removeFrontInst(DynInstPtr &inst);
514
515    /** Remove all instructions that are not currently in the ROB.
516     *  There's also an option to not squash delay slot instructions.*/
517    void removeInstsNotInROB(unsigned tid);
518
519    /** Remove all instructions younger than the given sequence number. */
520    void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
521
522    /** Removes the instruction pointed to by the iterator. */
523    inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
524
525    /** Cleans up all instructions on the remove list. */
526    void cleanUpRemovedInsts();
527
528    /** Debug function to print all instructions on the list. */
529    void dumpInsts();
530
531  public:
532    /** List of all the instructions in flight. */
533    std::list<DynInstPtr> instList;
534
535    /** List of all the instructions that will be removed at the end of this
536     *  cycle.
537     */
538    std::queue<ListIt> removeList;
539
540#ifdef DEBUG
541    /** Debug structure to keep track of the sequence numbers still in
542     * flight.
543     */
544    std::set<InstSeqNum> snList;
545#endif
546
547    /** Records if instructions need to be removed this cycle due to
548     *  being retired or squashed.
549     */
550    bool removeInstsThisCycle;
551
552  protected:
553    /** The fetch stage. */
554    typename CPUPolicy::Fetch fetch;
555
556    /** The decode stage. */
557    typename CPUPolicy::Decode decode;
558
559    /** The dispatch stage. */
560    typename CPUPolicy::Rename rename;
561
562    /** The issue/execute/writeback stages. */
563    typename CPUPolicy::IEW iew;
564
565    /** The commit stage. */
566    typename CPUPolicy::Commit commit;
567
568    /** The register file. */
569    typename CPUPolicy::RegFile regFile;
570
571    /** The free list. */
572    typename CPUPolicy::FreeList freeList;
573
574    /** The rename map. */
575    typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads];
576
577    /** The commit rename map. */
578    typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads];
579
580    /** The re-order buffer. */
581    typename CPUPolicy::ROB rob;
582
583    /** Active Threads List */
584    std::list<unsigned> activeThreads;
585
586    /** Integer Register Scoreboard */
587    Scoreboard scoreboard;
588
589  public:
590    /** Enum to give each stage a specific index, so when calling
591     *  activateStage() or deactivateStage(), they can specify which stage
592     *  is being activated/deactivated.
593     */
594    enum StageIdx {
595        FetchIdx,
596        DecodeIdx,
597        RenameIdx,
598        IEWIdx,
599        CommitIdx,
600        NumStages };
601
602    /** Typedefs from the Impl to get the structs that each of the
603     *  time buffers should use.
604     */
605    typedef typename CPUPolicy::TimeStruct TimeStruct;
606
607    typedef typename CPUPolicy::FetchStruct FetchStruct;
608
609    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
610
611    typedef typename CPUPolicy::RenameStruct RenameStruct;
612
613    typedef typename CPUPolicy::IEWStruct IEWStruct;
614
615    /** The main time buffer to do backwards communication. */
616    TimeBuffer<TimeStruct> timeBuffer;
617
618    /** The fetch stage's instruction queue. */
619    TimeBuffer<FetchStruct> fetchQueue;
620
621    /** The decode stage's instruction queue. */
622    TimeBuffer<DecodeStruct> decodeQueue;
623
624    /** The rename stage's instruction queue. */
625    TimeBuffer<RenameStruct> renameQueue;
626
627    /** The IEW stage's instruction queue. */
628    TimeBuffer<IEWStruct> iewQueue;
629
630  private:
631    /** The activity recorder; used to tell if the CPU has any
632     * activity remaining or if it can go to idle and deschedule
633     * itself.
634     */
635    ActivityRecorder activityRec;
636
637  public:
638    /** Records that there was time buffer activity this cycle. */
639    void activityThisCycle() { activityRec.activity(); }
640
641    /** Changes a stage's status to active within the activity recorder. */
642    void activateStage(const StageIdx idx)
643    { activityRec.activateStage(idx); }
644
645    /** Changes a stage's status to inactive within the activity recorder. */
646    void deactivateStage(const StageIdx idx)
647    { activityRec.deactivateStage(idx); }
648
649    /** Wakes the CPU, rescheduling the CPU if it's not already active. */
650    void wakeCPU();
651
652    /** Gets a free thread id. Use if thread ids change across system. */
653    int getFreeTid();
654
655  public:
656    /** Returns a pointer to a thread context. */
657    ThreadContext *tcBase(unsigned tid)
658    {
659        return thread[tid]->getTC();
660    }
661
662    /** The global sequence number counter. */
663    InstSeqNum globalSeqNum;//[Impl::MaxThreads];
664
665#if USE_CHECKER
666    /** Pointer to the checker, which can dynamically verify
667     * instruction results at run time.  This can be set to NULL if it
668     * is not being used.
669     */
670    Checker<DynInstPtr> *checker;
671#endif
672
673#if FULL_SYSTEM
674    /** Pointer to the system. */
675    System *system;
676
677    /** Pointer to physical memory. */
678    PhysicalMemory *physmem;
679#endif
680
681    /** Event to call process() on once draining has completed. */
682    Event *drainEvent;
683
684    /** Counter of how many stages have completed draining. */
685    int drainCount;
686
687    /** Pointers to all of the threads in the CPU. */
688    std::vector<Thread *> thread;
689
690    /** Whether or not the CPU should defer its registration. */
691    bool deferRegistration;
692
693    /** Is there a context switch pending? */
694    bool contextSwitch;
695
696    /** Threads Scheduled to Enter CPU */
697    std::list<int> cpuWaitList;
698
699    /** The cycle that the CPU was last running, used for statistics. */
700    Tick lastRunningCycle;
701
702    /** The cycle that the CPU was last activated by a new thread*/
703    Tick lastActivatedCycle;
704
705    /** Number of Threads CPU can process */
706    unsigned numThreads;
707
708    /** Mapping for system thread id to cpu id */
709    std::map<unsigned,unsigned> threadMap;
710
711    /** Available thread ids in the cpu*/
712    std::vector<unsigned> tids;
713
714    /** Stat for total number of times the CPU is descheduled. */
715    Stats::Scalar<> timesIdled;
716    /** Stat for total number of cycles the CPU spends descheduled. */
717    Stats::Scalar<> idleCycles;
718    /** Stat for the number of committed instructions per thread. */
719    Stats::Vector<> committedInsts;
720    /** Stat for the total number of committed instructions. */
721    Stats::Scalar<> totalCommittedInsts;
722    /** Stat for the CPI per thread. */
723    Stats::Formula cpi;
724    /** Stat for the total CPI. */
725    Stats::Formula totalCpi;
726    /** Stat for the IPC per thread. */
727    Stats::Formula ipc;
728    /** Stat for the total IPC. */
729    Stats::Formula totalIpc;
730};
731
732#endif // __CPU_O3_CPU_HH__
733