cpu.hh revision 14194:967b9c450b04
1/*
2 * Copyright (c) 2011-2013, 2016-2019 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder.  You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2005 The Regents of The University of Michigan
16 * Copyright (c) 2011 Regents of the University of California
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met: redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer;
23 * redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution;
26 * neither the name of the copyright holders nor the names of its
27 * contributors may be used to endorse or promote products derived from
28 * this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * Authors: Kevin Lim
43 *          Korey Sewell
44 *          Rick Strong
45 */
46
47#ifndef __CPU_O3_CPU_HH__
48#define __CPU_O3_CPU_HH__
49
50#include <iostream>
51#include <list>
52#include <queue>
53#include <set>
54#include <vector>
55
56#include "arch/generic/types.hh"
57#include "arch/types.hh"
58#include "base/statistics.hh"
59#include "config/the_isa.hh"
60#include "cpu/o3/comm.hh"
61#include "cpu/o3/cpu_policy.hh"
62#include "cpu/o3/scoreboard.hh"
63#include "cpu/o3/thread_state.hh"
64#include "cpu/activity.hh"
65#include "cpu/base.hh"
66#include "cpu/simple_thread.hh"
67#include "cpu/timebuf.hh"
68//#include "cpu/o3/thread_context.hh"
69#include "params/DerivO3CPU.hh"
70#include "sim/process.hh"
71
72template <class>
73class Checker;
74class ThreadContext;
75template <class>
76class O3ThreadContext;
77
78class Checkpoint;
79class Process;
80
81struct BaseCPUParams;
82
83class BaseO3CPU : public BaseCPU
84{
85    //Stuff that's pretty ISA independent will go here.
86  public:
87    BaseO3CPU(BaseCPUParams *params);
88
89    void regStats();
90};
91
92/**
93 * FullO3CPU class, has each of the stages (fetch through commit)
94 * within it, as well as all of the time buffers between stages.  The
95 * tick() function for the CPU is defined here.
96 */
97template <class Impl>
98class FullO3CPU : public BaseO3CPU
99{
100  public:
101    // Typedefs from the Impl here.
102    typedef typename Impl::CPUPol CPUPolicy;
103    typedef typename Impl::DynInstPtr DynInstPtr;
104    typedef typename Impl::O3CPU O3CPU;
105
106    using VecElem =  TheISA::VecElem;
107    using VecRegContainer =  TheISA::VecRegContainer;
108
109    using VecPredRegContainer = TheISA::VecPredRegContainer;
110
111    typedef O3ThreadState<Impl> ImplState;
112    typedef O3ThreadState<Impl> Thread;
113
114    typedef typename std::list<DynInstPtr>::iterator ListIt;
115
116    friend class O3ThreadContext<Impl>;
117
118  public:
119    enum Status {
120        Running,
121        Idle,
122        Halted,
123        Blocked,
124        SwitchedOut
125    };
126
127    BaseTLB *itb;
128    BaseTLB *dtb;
129    using LSQRequest = typename LSQ<Impl>::LSQRequest;
130
131    /** Overall CPU status. */
132    Status _status;
133
134  private:
135
136    /**
137     * IcachePort class for instruction fetch.
138     */
139    class IcachePort : public MasterPort
140    {
141      protected:
142        /** Pointer to fetch. */
143        DefaultFetch<Impl> *fetch;
144
145      public:
146        /** Default constructor. */
147        IcachePort(DefaultFetch<Impl> *_fetch, FullO3CPU<Impl>* _cpu)
148            : MasterPort(_cpu->name() + ".icache_port", _cpu), fetch(_fetch)
149        { }
150
151      protected:
152
153        /** Timing version of receive.  Handles setting fetch to the
154         * proper status to start fetching. */
155        virtual bool recvTimingResp(PacketPtr pkt);
156
157        /** Handles doing a retry of a failed fetch. */
158        virtual void recvReqRetry();
159    };
160
161    /** The tick event used for scheduling CPU ticks. */
162    EventFunctionWrapper tickEvent;
163
164    /** The exit event used for terminating all ready-to-exit threads */
165    EventFunctionWrapper threadExitEvent;
166
167    /** Schedule tick event, regardless of its current state. */
168    void scheduleTickEvent(Cycles delay)
169    {
170        if (tickEvent.squashed())
171            reschedule(tickEvent, clockEdge(delay));
172        else if (!tickEvent.scheduled())
173            schedule(tickEvent, clockEdge(delay));
174    }
175
176    /** Unschedule tick event, regardless of its current state. */
177    void unscheduleTickEvent()
178    {
179        if (tickEvent.scheduled())
180            tickEvent.squash();
181    }
182
183    /**
184     * Check if the pipeline has drained and signal drain done.
185     *
186     * This method checks if a drain has been requested and if the CPU
187     * has drained successfully (i.e., there are no instructions in
188     * the pipeline). If the CPU has drained, it deschedules the tick
189     * event and signals the drain manager.
190     *
191     * @return False if a drain hasn't been requested or the CPU
192     * hasn't drained, true otherwise.
193     */
194    bool tryDrain();
195
196    /**
197     * Perform sanity checks after a drain.
198     *
199     * This method is called from drain() when it has determined that
200     * the CPU is fully drained when gem5 is compiled with the NDEBUG
201     * macro undefined. The intention of this method is to do more
202     * extensive tests than the isDrained() method to weed out any
203     * draining bugs.
204     */
205    void drainSanityCheck() const;
206
207    /** Check if a system is in a drained state. */
208    bool isCpuDrained() const;
209
210  public:
211    /** Constructs a CPU with the given parameters. */
212    FullO3CPU(DerivO3CPUParams *params);
213    /** Destructor. */
214    ~FullO3CPU();
215
216    /** Registers statistics. */
217    void regStats() override;
218
219    ProbePointArg<PacketPtr> *ppInstAccessComplete;
220    ProbePointArg<std::pair<DynInstPtr, PacketPtr> > *ppDataAccessComplete;
221
222    /** Register probe points. */
223    void regProbePoints() override;
224
225    void demapPage(Addr vaddr, uint64_t asn)
226    {
227        this->itb->demapPage(vaddr, asn);
228        this->dtb->demapPage(vaddr, asn);
229    }
230
231    void demapInstPage(Addr vaddr, uint64_t asn)
232    {
233        this->itb->demapPage(vaddr, asn);
234    }
235
236    void demapDataPage(Addr vaddr, uint64_t asn)
237    {
238        this->dtb->demapPage(vaddr, asn);
239    }
240
241    /** Ticks CPU, calling tick() on each stage, and checking the overall
242     *  activity to see if the CPU should deschedule itself.
243     */
244    void tick();
245
246    /** Initialize the CPU */
247    void init() override;
248
249    void startup() override;
250
251    /** Returns the Number of Active Threads in the CPU */
252    int numActiveThreads()
253    { return activeThreads.size(); }
254
255    /** Add Thread to Active Threads List */
256    void activateThread(ThreadID tid);
257
258    /** Remove Thread from Active Threads List */
259    void deactivateThread(ThreadID tid);
260
261    /** Setup CPU to insert a thread's context */
262    void insertThread(ThreadID tid);
263
264    /** Remove all of a thread's context from CPU */
265    void removeThread(ThreadID tid);
266
267    /** Count the Total Instructions Committed in the CPU. */
268    Counter totalInsts() const override;
269
270    /** Count the Total Ops (including micro ops) committed in the CPU. */
271    Counter totalOps() const override;
272
273    /** Add Thread to Active Threads List. */
274    void activateContext(ThreadID tid) override;
275
276    /** Remove Thread from Active Threads List */
277    void suspendContext(ThreadID tid) override;
278
279    /** Remove Thread from Active Threads List &&
280     *  Remove Thread Context from CPU.
281     */
282    void haltContext(ThreadID tid) override;
283
284    /** Update The Order In Which We Process Threads. */
285    void updateThreadPriority();
286
287    /** Is the CPU draining? */
288    bool isDraining() const { return drainState() == DrainState::Draining; }
289
290    void serializeThread(CheckpointOut &cp, ThreadID tid) const override;
291    void unserializeThread(CheckpointIn &cp, ThreadID tid) override;
292
293    /** Insert tid to the list of threads trying to exit */
294    void addThreadToExitingList(ThreadID tid);
295
296    /** Is the thread trying to exit? */
297    bool isThreadExiting(ThreadID tid) const;
298
299    /**
300     *  If a thread is trying to exit and its corresponding trap event
301     *  has been completed, schedule an event to terminate the thread.
302     */
303    void scheduleThreadExitEvent(ThreadID tid);
304
305    /** Terminate all threads that are ready to exit */
306    void exitThreads();
307
308  public:
309    /** Executes a syscall.
310     * @todo: Determine if this needs to be virtual.
311     */
312    void syscall(int64_t callnum, ThreadID tid, Fault *fault);
313
314    /** Starts draining the CPU's pipeline of all instructions in
315     * order to stop all memory accesses. */
316    DrainState drain() override;
317
318    /** Resumes execution after a drain. */
319    void drainResume() override;
320
321    /**
322     * Commit has reached a safe point to drain a thread.
323     *
324     * Commit calls this method to inform the pipeline that it has
325     * reached a point where it is not executed microcode and is about
326     * to squash uncommitted instructions to fully drain the pipeline.
327     */
328    void commitDrained(ThreadID tid);
329
330    /** Switches out this CPU. */
331    void switchOut() override;
332
333    /** Takes over from another CPU. */
334    void takeOverFrom(BaseCPU *oldCPU) override;
335
336    void verifyMemoryMode() const override;
337
338    /** Get the current instruction sequence number, and increment it. */
339    InstSeqNum getAndIncrementInstSeq()
340    { return globalSeqNum++; }
341
342    /** Traps to handle given fault. */
343    void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst);
344
345    /** Check if a change in renaming is needed for vector registers.
346     * The vecMode variable is updated and propagated to rename maps.
347     *
348     * @param tid ThreadID
349     * @param freelist list of free registers
350     */
351    void switchRenameMode(ThreadID tid, UnifiedFreeList* freelist);
352
353    /** Returns the Fault for any valid interrupt. */
354    Fault getInterrupts();
355
356    /** Processes any an interrupt fault. */
357    void processInterrupts(const Fault &interrupt);
358
359    /** Halts the CPU. */
360    void halt() { panic("Halt not implemented!\n"); }
361
362    /** Register accessors.  Index refers to the physical register index. */
363
364    /** Reads a miscellaneous register. */
365    RegVal readMiscRegNoEffect(int misc_reg, ThreadID tid) const;
366
367    /** Reads a misc. register, including any side effects the read
368     * might have as defined by the architecture.
369     */
370    RegVal readMiscReg(int misc_reg, ThreadID tid);
371
372    /** Sets a miscellaneous register. */
373    void setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid);
374
375    /** Sets a misc. register, including any side effects the write
376     * might have as defined by the architecture.
377     */
378    void setMiscReg(int misc_reg, RegVal val, ThreadID tid);
379
380    RegVal readIntReg(PhysRegIdPtr phys_reg);
381
382    RegVal readFloatReg(PhysRegIdPtr phys_reg);
383
384    const VecRegContainer& readVecReg(PhysRegIdPtr reg_idx) const;
385
386    /**
387     * Read physical vector register for modification.
388     */
389    VecRegContainer& getWritableVecReg(PhysRegIdPtr reg_idx);
390
391    /** Returns current vector renaming mode */
392    Enums::VecRegRenameMode vecRenameMode() const { return vecMode; }
393
394    /** Sets the current vector renaming mode */
395    void vecRenameMode(Enums::VecRegRenameMode vec_mode)
396    { vecMode = vec_mode; }
397
398    /**
399     * Read physical vector register lane
400     */
401    template<typename VecElem, int LaneIdx>
402    VecLaneT<VecElem, true>
403    readVecLane(PhysRegIdPtr phys_reg) const
404    {
405        vecRegfileReads++;
406        return regFile.readVecLane<VecElem, LaneIdx>(phys_reg);
407    }
408
409    /**
410     * Read physical vector register lane
411     */
412    template<typename VecElem>
413    VecLaneT<VecElem, true>
414    readVecLane(PhysRegIdPtr phys_reg) const
415    {
416        vecRegfileReads++;
417        return regFile.readVecLane<VecElem>(phys_reg);
418    }
419
420    /** Write a lane of the destination vector register. */
421    template<typename LD>
422    void
423    setVecLane(PhysRegIdPtr phys_reg, const LD& val)
424    {
425        vecRegfileWrites++;
426        return regFile.setVecLane(phys_reg, val);
427    }
428
429    const VecElem& readVecElem(PhysRegIdPtr reg_idx) const;
430
431    const VecPredRegContainer& readVecPredReg(PhysRegIdPtr reg_idx) const;
432
433    VecPredRegContainer& getWritableVecPredReg(PhysRegIdPtr reg_idx);
434
435    RegVal readCCReg(PhysRegIdPtr phys_reg);
436
437    void setIntReg(PhysRegIdPtr phys_reg, RegVal val);
438
439    void setFloatReg(PhysRegIdPtr phys_reg, RegVal val);
440
441    void setVecReg(PhysRegIdPtr reg_idx, const VecRegContainer& val);
442
443    void setVecElem(PhysRegIdPtr reg_idx, const VecElem& val);
444
445    void setVecPredReg(PhysRegIdPtr reg_idx, const VecPredRegContainer& val);
446
447    void setCCReg(PhysRegIdPtr phys_reg, RegVal val);
448
449    RegVal readArchIntReg(int reg_idx, ThreadID tid);
450
451    RegVal readArchFloatReg(int reg_idx, ThreadID tid);
452
453    const VecRegContainer& readArchVecReg(int reg_idx, ThreadID tid) const;
454    /** Read architectural vector register for modification. */
455    VecRegContainer& getWritableArchVecReg(int reg_idx, ThreadID tid);
456
457    /** Read architectural vector register lane. */
458    template<typename VecElem>
459    VecLaneT<VecElem, true>
460    readArchVecLane(int reg_idx, int lId, ThreadID tid) const
461    {
462        PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
463                    RegId(VecRegClass, reg_idx));
464        return readVecLane<VecElem>(phys_reg);
465    }
466
467
468    /** Write a lane of the destination vector register. */
469    template<typename LD>
470    void
471    setArchVecLane(int reg_idx, int lId, ThreadID tid, const LD& val)
472    {
473        PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
474                    RegId(VecRegClass, reg_idx));
475        setVecLane(phys_reg, val);
476    }
477
478    const VecElem& readArchVecElem(const RegIndex& reg_idx,
479                                   const ElemIndex& ldx, ThreadID tid) const;
480
481    const VecPredRegContainer& readArchVecPredReg(int reg_idx,
482                                                  ThreadID tid) const;
483
484    VecPredRegContainer& getWritableArchVecPredReg(int reg_idx, ThreadID tid);
485
486    RegVal readArchCCReg(int reg_idx, ThreadID tid);
487
488    /** Architectural register accessors.  Looks up in the commit
489     * rename table to obtain the true physical index of the
490     * architected register first, then accesses that physical
491     * register.
492     */
493    void setArchIntReg(int reg_idx, RegVal val, ThreadID tid);
494
495    void setArchFloatReg(int reg_idx, RegVal val, ThreadID tid);
496
497    void setArchVecPredReg(int reg_idx, const VecPredRegContainer& val,
498                           ThreadID tid);
499
500    void setArchVecReg(int reg_idx, const VecRegContainer& val, ThreadID tid);
501
502    void setArchVecElem(const RegIndex& reg_idx, const ElemIndex& ldx,
503                        const VecElem& val, ThreadID tid);
504
505    void setArchCCReg(int reg_idx, RegVal val, ThreadID tid);
506
507    /** Sets the commit PC state of a specific thread. */
508    void pcState(const TheISA::PCState &newPCState, ThreadID tid);
509
510    /** Reads the commit PC state of a specific thread. */
511    TheISA::PCState pcState(ThreadID tid);
512
513    /** Reads the commit PC of a specific thread. */
514    Addr instAddr(ThreadID tid);
515
516    /** Reads the commit micro PC of a specific thread. */
517    MicroPC microPC(ThreadID tid);
518
519    /** Reads the next PC of a specific thread. */
520    Addr nextInstAddr(ThreadID tid);
521
522    /** Initiates a squash of all in-flight instructions for a given
523     * thread.  The source of the squash is an external update of
524     * state through the TC.
525     */
526    void squashFromTC(ThreadID tid);
527
528    /** Function to add instruction onto the head of the list of the
529     *  instructions.  Used when new instructions are fetched.
530     */
531    ListIt addInst(const DynInstPtr &inst);
532
533    /** Function to tell the CPU that an instruction has completed. */
534    void instDone(ThreadID tid, const DynInstPtr &inst);
535
536    /** Remove an instruction from the front end of the list.  There's
537     *  no restriction on location of the instruction.
538     */
539    void removeFrontInst(const DynInstPtr &inst);
540
541    /** Remove all instructions that are not currently in the ROB.
542     *  There's also an option to not squash delay slot instructions.*/
543    void removeInstsNotInROB(ThreadID tid);
544
545    /** Remove all instructions younger than the given sequence number. */
546    void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid);
547
548    /** Removes the instruction pointed to by the iterator. */
549    inline void squashInstIt(const ListIt &instIt, ThreadID tid);
550
551    /** Cleans up all instructions on the remove list. */
552    void cleanUpRemovedInsts();
553
554    /** Debug function to print all instructions on the list. */
555    void dumpInsts();
556
557  public:
558#ifndef NDEBUG
559    /** Count of total number of dynamic instructions in flight. */
560    int instcount;
561#endif
562
563    /** List of all the instructions in flight. */
564    std::list<DynInstPtr> instList;
565
566    /** List of all the instructions that will be removed at the end of this
567     *  cycle.
568     */
569    std::queue<ListIt> removeList;
570
571#ifdef DEBUG
572    /** Debug structure to keep track of the sequence numbers still in
573     * flight.
574     */
575    std::set<InstSeqNum> snList;
576#endif
577
578    /** Records if instructions need to be removed this cycle due to
579     *  being retired or squashed.
580     */
581    bool removeInstsThisCycle;
582
583  protected:
584    /** The fetch stage. */
585    typename CPUPolicy::Fetch fetch;
586
587    /** The decode stage. */
588    typename CPUPolicy::Decode decode;
589
590    /** The dispatch stage. */
591    typename CPUPolicy::Rename rename;
592
593    /** The issue/execute/writeback stages. */
594    typename CPUPolicy::IEW iew;
595
596    /** The commit stage. */
597    typename CPUPolicy::Commit commit;
598
599    /** The rename mode of the vector registers */
600    Enums::VecRegRenameMode vecMode;
601
602    /** The register file. */
603    PhysRegFile regFile;
604
605    /** The free list. */
606    typename CPUPolicy::FreeList freeList;
607
608    /** The rename map. */
609    typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads];
610
611    /** The commit rename map. */
612    typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads];
613
614    /** The re-order buffer. */
615    typename CPUPolicy::ROB rob;
616
617    /** Active Threads List */
618    std::list<ThreadID> activeThreads;
619
620    /**
621     *  This is a list of threads that are trying to exit. Each thread id
622     *  is mapped to a boolean value denoting whether the thread is ready
623     *  to exit.
624     */
625    std::unordered_map<ThreadID, bool> exitingThreads;
626
627    /** Integer Register Scoreboard */
628    Scoreboard scoreboard;
629
630    std::vector<TheISA::ISA *> isa;
631
632    /** Instruction port. Note that it has to appear after the fetch stage. */
633    IcachePort icachePort;
634
635  public:
636    /** Enum to give each stage a specific index, so when calling
637     *  activateStage() or deactivateStage(), they can specify which stage
638     *  is being activated/deactivated.
639     */
640    enum StageIdx {
641        FetchIdx,
642        DecodeIdx,
643        RenameIdx,
644        IEWIdx,
645        CommitIdx,
646        NumStages };
647
648    /** Typedefs from the Impl to get the structs that each of the
649     *  time buffers should use.
650     */
651    typedef typename CPUPolicy::TimeStruct TimeStruct;
652
653    typedef typename CPUPolicy::FetchStruct FetchStruct;
654
655    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
656
657    typedef typename CPUPolicy::RenameStruct RenameStruct;
658
659    typedef typename CPUPolicy::IEWStruct IEWStruct;
660
661    /** The main time buffer to do backwards communication. */
662    TimeBuffer<TimeStruct> timeBuffer;
663
664    /** The fetch stage's instruction queue. */
665    TimeBuffer<FetchStruct> fetchQueue;
666
667    /** The decode stage's instruction queue. */
668    TimeBuffer<DecodeStruct> decodeQueue;
669
670    /** The rename stage's instruction queue. */
671    TimeBuffer<RenameStruct> renameQueue;
672
673    /** The IEW stage's instruction queue. */
674    TimeBuffer<IEWStruct> iewQueue;
675
676  private:
677    /** The activity recorder; used to tell if the CPU has any
678     * activity remaining or if it can go to idle and deschedule
679     * itself.
680     */
681    ActivityRecorder activityRec;
682
683  public:
684    /** Records that there was time buffer activity this cycle. */
685    void activityThisCycle() { activityRec.activity(); }
686
687    /** Changes a stage's status to active within the activity recorder. */
688    void activateStage(const StageIdx idx)
689    { activityRec.activateStage(idx); }
690
691    /** Changes a stage's status to inactive within the activity recorder. */
692    void deactivateStage(const StageIdx idx)
693    { activityRec.deactivateStage(idx); }
694
695    /** Wakes the CPU, rescheduling the CPU if it's not already active. */
696    void wakeCPU();
697
698    virtual void wakeup(ThreadID tid) override;
699
700    /** Gets a free thread id. Use if thread ids change across system. */
701    ThreadID getFreeTid();
702
703  public:
704    /** Returns a pointer to a thread context. */
705    ThreadContext *
706    tcBase(ThreadID tid)
707    {
708        return thread[tid]->getTC();
709    }
710
711    /** The global sequence number counter. */
712    InstSeqNum globalSeqNum;//[Impl::MaxThreads];
713
714    /** Pointer to the checker, which can dynamically verify
715     * instruction results at run time.  This can be set to NULL if it
716     * is not being used.
717     */
718    Checker<Impl> *checker;
719
720    /** Pointer to the system. */
721    System *system;
722
723    /** Pointers to all of the threads in the CPU. */
724    std::vector<Thread *> thread;
725
726    /** Threads Scheduled to Enter CPU */
727    std::list<int> cpuWaitList;
728
729    /** The cycle that the CPU was last running, used for statistics. */
730    Cycles lastRunningCycle;
731
732    /** The cycle that the CPU was last activated by a new thread*/
733    Tick lastActivatedCycle;
734
735    /** Mapping for system thread id to cpu id */
736    std::map<ThreadID, unsigned> threadMap;
737
738    /** Available thread ids in the cpu*/
739    std::vector<ThreadID> tids;
740
741    /** CPU pushRequest function, forwards request to LSQ. */
742    Fault pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data,
743                      unsigned int size, Addr addr, Request::Flags flags,
744                      uint64_t *res, AtomicOpFunctor *amo_op = nullptr,
745                      const std::vector<bool>& byteEnable =
746                          std::vector<bool>())
747
748    {
749        return iew.ldstQueue.pushRequest(inst, isLoad, data, size, addr,
750                flags, res, amo_op, byteEnable);
751    }
752
753    /** CPU read function, forwards read to LSQ. */
754    Fault read(LSQRequest* req, int load_idx)
755    {
756        return this->iew.ldstQueue.read(req, load_idx);
757    }
758
759    /** CPU write function, forwards write to LSQ. */
760    Fault write(LSQRequest* req, uint8_t *data, int store_idx)
761    {
762        return this->iew.ldstQueue.write(req, data, store_idx);
763    }
764
765    /** Used by the fetch unit to get a hold of the instruction port. */
766    MasterPort &getInstPort() override { return icachePort; }
767
768    /** Get the dcache port (used to find block size for translations). */
769    MasterPort &
770    getDataPort() override
771    {
772        return this->iew.ldstQueue.getDataPort();
773    }
774
775    /** Stat for total number of times the CPU is descheduled. */
776    Stats::Scalar timesIdled;
777    /** Stat for total number of cycles the CPU spends descheduled. */
778    Stats::Scalar idleCycles;
779    /** Stat for total number of cycles the CPU spends descheduled due to a
780     * quiesce operation or waiting for an interrupt. */
781    Stats::Scalar quiesceCycles;
782    /** Stat for the number of committed instructions per thread. */
783    Stats::Vector committedInsts;
784    /** Stat for the number of committed ops (including micro ops) per thread. */
785    Stats::Vector committedOps;
786    /** Stat for the CPI per thread. */
787    Stats::Formula cpi;
788    /** Stat for the total CPI. */
789    Stats::Formula totalCpi;
790    /** Stat for the IPC per thread. */
791    Stats::Formula ipc;
792    /** Stat for the total IPC. */
793    Stats::Formula totalIpc;
794
795    //number of integer register file accesses
796    Stats::Scalar intRegfileReads;
797    Stats::Scalar intRegfileWrites;
798    //number of float register file accesses
799    Stats::Scalar fpRegfileReads;
800    Stats::Scalar fpRegfileWrites;
801    //number of vector register file accesses
802    mutable Stats::Scalar vecRegfileReads;
803    Stats::Scalar vecRegfileWrites;
804    //number of predicate register file accesses
805    mutable Stats::Scalar vecPredRegfileReads;
806    Stats::Scalar vecPredRegfileWrites;
807    //number of CC register file accesses
808    Stats::Scalar ccRegfileReads;
809    Stats::Scalar ccRegfileWrites;
810    //number of misc
811    Stats::Scalar miscRegfileReads;
812    Stats::Scalar miscRegfileWrites;
813};
814
815#endif // __CPU_O3_CPU_HH__
816