base.hh revision 180
12292SN/A/*
22329SN/A * Copyright (c) 2003 The Regents of The University of Michigan
32292SN/A * All rights reserved.
42292SN/A *
52292SN/A * Redistribution and use in source and binary forms, with or without
62292SN/A * modification, are permitted provided that the following conditions are
72292SN/A * met: redistributions of source code must retain the above copyright
82292SN/A * notice, this list of conditions and the following disclaimer;
92292SN/A * redistributions in binary form must reproduce the above copyright
102292SN/A * notice, this list of conditions and the following disclaimer in the
112292SN/A * documentation and/or other materials provided with the distribution;
122292SN/A * neither the name of the copyright holders nor the names of its
132292SN/A * contributors may be used to endorse or promote products derived from
142292SN/A * this software without specific prior written permission.
152292SN/A *
162292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272689Sktlim@umich.edu */
282689Sktlim@umich.edu
292689Sktlim@umich.edu#ifndef __SIMPLE_CPU_HH__
302292SN/A#define __SIMPLE_CPU_HH__
312292SN/A
322292SN/A#include "cpu/base_cpu.hh"
332292SN/A#include "sim/eventq.hh"
342292SN/A#include "base/loader/symtab.hh"
352329SN/A#include "cpu/pc_event.hh"
364395Ssaidi@eecs.umich.edu#include "base/statistics.hh"
372292SN/A
382292SN/A
392292SN/A// forward declarations
402329SN/A#ifdef FULL_SYSTEM
413326Sktlim@umich.educlass Processor;
422292SN/Aclass Kernel;
435386Sstever@gmail.comclass AlphaItb;
442292SN/Aclass AlphaDtb;
452292SN/Aclass PhysicalMemory;
463348Sbinkertn@umich.edu
472669Sktlim@umich.educlass RemoteGDB;
482292SN/Aclass GDBListener;
492292SN/A#endif // FULL_SYSTEM
502329SN/A
512329SN/Aclass MemInterface;
522329SN/Aclass IniFile;
532329SN/A
542329SN/Anamespace Trace {
552329SN/A    class InstRecord;
562329SN/A}
572329SN/A
582329SN/Aclass SimpleCPU : public BaseCPU
592329SN/A{
602292SN/A  public:
612292SN/A    // main simulation loop (one cycle)
622292SN/A    void tick();
632292SN/A
642292SN/A  private:
652292SN/A    class TickEvent : public Event
662292SN/A    {
672733Sktlim@umich.edu      private:
682292SN/A        SimpleCPU *cpu;
692292SN/A
702907Sktlim@umich.edu      public:
712292SN/A        TickEvent(SimpleCPU *c)
722292SN/A            : Event(&mainEventQueue, 100), cpu(c) { }
732292SN/A        void process() { cpu->tick(); }
742292SN/A        virtual const char *description() { return "tick event"; }
752292SN/A    };
762292SN/A
772292SN/A    TickEvent tickEvent;
784329Sktlim@umich.edu
794329Sktlim@umich.edu  private:
802292SN/A    Trace::InstRecord *traceData;
812292SN/A    template<typename T>
822292SN/A    void trace_data(T data) {
832292SN/A      if (traceData) {
842727Sktlim@umich.edu        traceData->setData(data);
852727Sktlim@umich.edu      }
862727Sktlim@umich.edu    };
872907Sktlim@umich.edu
884329Sktlim@umich.edu  public:
892907Sktlim@umich.edu    //
902348SN/A    enum Status {
912307SN/A        Running,
922307SN/A        Idle,
932348SN/A        IcacheMissStall,
942307SN/A        IcacheMissComplete,
952307SN/A        DcacheMissStall,
962348SN/A        SwitchedOut
972307SN/A    };
982307SN/A
992292SN/A  private:
1002292SN/A    Status _status;
1012292SN/A
1022292SN/A  public:
1032292SN/A    void post_interrupt(int int_num, int index);
1042292SN/A
1052292SN/A    void zero_fill_64(Addr addr) {
1062292SN/A      static int warned = 0;
1072292SN/A      if (!warned) {
1082292SN/A        warn ("WH64 is not implemented");
1092292SN/A        warned = 1;
1102292SN/A      }
1112292SN/A    };
1122292SN/A
1132292SN/A#ifdef FULL_SYSTEM
1142292SN/A
1152292SN/A    SimpleCPU(const std::string &_name,
1162329SN/A              System *_system,
1172292SN/A              Counter max_insts_any_thread, Counter max_insts_all_threads,
1182292SN/A              Counter max_loads_any_thread, Counter max_loads_all_threads,
1192292SN/A              AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem,
1202292SN/A              MemInterface *icache_interface, MemInterface *dcache_interface,
1212292SN/A              Tick freq);
1222292SN/A
1232292SN/A#else
1242292SN/A
1252292SN/A    SimpleCPU(const std::string &_name, Process *_process,
1262292SN/A              Counter max_insts_any_thread,
1272292SN/A              Counter max_insts_all_threads,
1282292SN/A              Counter max_loads_any_thread,
1292292SN/A              Counter max_loads_all_threads,
1302292SN/A              MemInterface *icache_interface, MemInterface *dcache_interface);
1312790Sktlim@umich.edu
1322790Sktlim@umich.edu#endif
1332669Sktlim@umich.edu
1342669Sktlim@umich.edu    virtual ~SimpleCPU();
1352292SN/A
1362292SN/A    // execution context
1372292SN/A    ExecContext *xc;
1382292SN/A
1392292SN/A    void registerExecContexts();
1402292SN/A
1412292SN/A    void switchOut();
1422292SN/A    void takeOverFrom(BaseCPU *oldCPU);
1432292SN/A
1442292SN/A#ifdef FULL_SYSTEM
1452292SN/A    Addr dbg_vtophys(Addr addr);
1462292SN/A
1472292SN/A    bool interval_stats;
1482292SN/A#endif
1492292SN/A
1502292SN/A    // L1 instruction cache
1512292SN/A    MemInterface *icacheInterface;
1522292SN/A
1532292SN/A    // L1 data cache
1542292SN/A    MemInterface *dcacheInterface;
1552292SN/A
1562292SN/A    // current instruction
1572292SN/A    MachInst inst;
1582329SN/A
1592292SN/A    // current fault status
1602292SN/A    Fault fault;
1612292SN/A
1622348SN/A    // Refcounted pointer to the one memory request.
1632292SN/A    MemReqPtr memReq;
1642292SN/A
1652292SN/A    class CacheCompletionEvent : public Event
1662348SN/A    {
1672292SN/A      private:
1682292SN/A        SimpleCPU *cpu;
1692292SN/A
1702348SN/A      public:
1712292SN/A        CacheCompletionEvent(SimpleCPU *_cpu);
1722292SN/A
1732292SN/A        virtual void process();
1742292SN/A        virtual const char *description();
1752292SN/A    };
1762292SN/A
1772292SN/A    CacheCompletionEvent cacheCompletionEvent;
1782292SN/A
1792292SN/A    Status status() const { return _status; }
1802292SN/A
1812292SN/A    virtual void execCtxStatusChg() {
1822292SN/A        if (xc) {
1832292SN/A            if (xc->status() == ExecContext::Active)
1842292SN/A                setStatus(Running);
1852292SN/A            else
1862292SN/A                setStatus(Idle);
1872292SN/A        }
1882292SN/A    }
1892292SN/A
1902292SN/A    void setStatus(Status new_status) {
1912292SN/A        Status old_status = status();
1922292SN/A
1932292SN/A        // We should never even get here if the CPU has been switched out.
1942292SN/A        assert(old_status != SwitchedOut);
1952292SN/A
1962292SN/A        _status = new_status;
1972292SN/A
1982292SN/A        switch (status()) {
1992292SN/A          case IcacheMissStall:
2002292SN/A            assert(old_status == Running);
2012292SN/A            lastIcacheStall = curTick;
2022292SN/A            if (tickEvent.scheduled())
2032292SN/A                tickEvent.squash();
2042292SN/A            break;
2052292SN/A
2062678Sktlim@umich.edu          case IcacheMissComplete:
2072678Sktlim@umich.edu            assert(old_status == IcacheMissStall);
2082292SN/A            if (tickEvent.squashed())
2092907Sktlim@umich.edu                tickEvent.reschedule(curTick + 1);
2102907Sktlim@umich.edu            else if (!tickEvent.scheduled())
2112907Sktlim@umich.edu                tickEvent.schedule(curTick + 1);
2122292SN/A            break;
2132698Sktlim@umich.edu
2142678Sktlim@umich.edu          case DcacheMissStall:
2152678Sktlim@umich.edu            assert(old_status == Running);
2162698Sktlim@umich.edu            lastDcacheStall = curTick;
2173349Sbinkertn@umich.edu            if (tickEvent.scheduled())
2182693Sktlim@umich.edu                tickEvent.squash();
2192292SN/A            break;
2202292SN/A
2212292SN/A          case Idle:
2222292SN/A            assert(old_status == Running);
2232292SN/A            last_idle = curTick;
2242292SN/A            if (tickEvent.scheduled())
2252292SN/A                tickEvent.squash();
2262292SN/A            break;
2272292SN/A
2282292SN/A          case Running:
2292292SN/A            assert(old_status == Idle ||
2302292SN/A                   old_status == DcacheMissStall ||
2312329SN/A                   old_status == IcacheMissComplete);
2322329SN/A            if (old_status == Idle)
2332329SN/A                idleCycles += curTick - last_idle;
2342329SN/A
2352292SN/A            if (tickEvent.squashed())
2362292SN/A                tickEvent.reschedule(curTick + 1);
2372733Sktlim@umich.edu            else if (!tickEvent.scheduled())
2382292SN/A                tickEvent.schedule(curTick + 1);
2392292SN/A            break;
2402292SN/A
2412292SN/A          default:
2422907Sktlim@umich.edu            panic("can't get here");
2432907Sktlim@umich.edu        }
2442669Sktlim@umich.edu    }
2452907Sktlim@umich.edu
2462907Sktlim@umich.edu    // statistics
2472292SN/A    void regStats();
2482698Sktlim@umich.edu
2495386Sstever@gmail.com    // number of simulated instructions
2502678Sktlim@umich.edu    Counter numInst;
2512678Sktlim@umich.edu    Statistics::Formula numInsts;
2522698Sktlim@umich.edu
2532678Sktlim@umich.edu    // number of simulated memory references
2542678Sktlim@umich.edu    Statistics::Scalar<> numMemRefs;
2552678Sktlim@umich.edu
2562678Sktlim@umich.edu    // number of simulated loads
2572698Sktlim@umich.edu    Counter numLoad;
2582678Sktlim@umich.edu
2592698Sktlim@umich.edu    // number of idle cycles
2602678Sktlim@umich.edu    Statistics::Scalar<> idleCycles;
2612698Sktlim@umich.edu    Statistics::Formula idleFraction;
2622678Sktlim@umich.edu    Counter last_idle;
2632698Sktlim@umich.edu
2642678Sktlim@umich.edu    // number of cycles stalled for I-cache misses
2652678Sktlim@umich.edu    Statistics::Scalar<> icacheStallCycles;
2662678Sktlim@umich.edu    Counter lastIcacheStall;
2672698Sktlim@umich.edu
2682678Sktlim@umich.edu    // number of cycles stalled for D-cache misses
2692678Sktlim@umich.edu    Statistics::Scalar<> dcacheStallCycles;
2702678Sktlim@umich.edu    Counter lastDcacheStall;
2712678Sktlim@umich.edu
2722678Sktlim@umich.edu    void processCacheCompletion();
2732678Sktlim@umich.edu
2742678Sktlim@umich.edu    virtual void serialize();
2752678Sktlim@umich.edu    virtual void unserialize(IniFile &db, const std::string &category,
2762678Sktlim@umich.edu                             ConfigNode *node);
2775336Shines@cs.fsu.edu
2782678Sktlim@umich.edu    template <class T>
2792678Sktlim@umich.edu    Fault read(Addr addr, T& data, unsigned flags);
2802698Sktlim@umich.edu
2812678Sktlim@umich.edu    template <class T>
2822678Sktlim@umich.edu    Fault write(T data, Addr addr, unsigned flags,
2832698Sktlim@umich.edu                        uint64_t *res);
2842678Sktlim@umich.edu
2852678Sktlim@umich.edu    Fault prefetch(Addr addr, unsigned flags)
2862678Sktlim@umich.edu    {
2872678Sktlim@umich.edu        // need to do this...
2882678Sktlim@umich.edu        return No_Fault;
2892678Sktlim@umich.edu    }
2902292SN/A
2912292SN/A    void writeHint(Addr addr, int size)
2922292SN/A    {
2932292SN/A        // need to do this...
2944326Sgblack@eecs.umich.edu    }
2952292SN/A};
2964326Sgblack@eecs.umich.edu
2974395Ssaidi@eecs.umich.edu#endif // __SIMPLE_CPU_HH__
2984326Sgblack@eecs.umich.edu