RubyDirectedTester.hh revision 7053
111420Sdavid.guillen@arm.com/*
211420Sdavid.guillen@arm.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
311420Sdavid.guillen@arm.com * Copyright (c) 2009 Advanced Micro Devices, Inc.
411420Sdavid.guillen@arm.com * All rights reserved.
511420Sdavid.guillen@arm.com *
611420Sdavid.guillen@arm.com * Redistribution and use in source and binary forms, with or without
711420Sdavid.guillen@arm.com * modification, are permitted provided that the following conditions are
811420Sdavid.guillen@arm.com * met: redistributions of source code must retain the above copyright
911420Sdavid.guillen@arm.com * notice, this list of conditions and the following disclaimer;
1011420Sdavid.guillen@arm.com * redistributions in binary form must reproduce the above copyright
1111420Sdavid.guillen@arm.com * notice, this list of conditions and the following disclaimer in the
1211420Sdavid.guillen@arm.com * documentation and/or other materials provided with the distribution;
1311420Sdavid.guillen@arm.com * neither the name of the copyright holders nor the names of its
1411420Sdavid.guillen@arm.com * contributors may be used to endorse or promote products derived from
1511420Sdavid.guillen@arm.com * this software without specific prior written permission.
1611420Sdavid.guillen@arm.com *
1711420Sdavid.guillen@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1811420Sdavid.guillen@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1911420Sdavid.guillen@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2011420Sdavid.guillen@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2111420Sdavid.guillen@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2211420Sdavid.guillen@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2311420Sdavid.guillen@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2411420Sdavid.guillen@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2511420Sdavid.guillen@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2611420Sdavid.guillen@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2711420Sdavid.guillen@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2811420Sdavid.guillen@arm.com */
2911420Sdavid.guillen@arm.com
3011420Sdavid.guillen@arm.com#ifndef __CPU_RUBYTEST_RUBYTESTER_HH__
3111420Sdavid.guillen@arm.com#define __CPU_RUBYTEST_RUBYTESTER_HH__
3211420Sdavid.guillen@arm.com
3311420Sdavid.guillen@arm.com#include "cpu/rubytest/CheckTable.hh"
3411420Sdavid.guillen@arm.com#include "mem/mem_object.hh"
3511420Sdavid.guillen@arm.com#include "mem/packet.hh"
3611420Sdavid.guillen@arm.com#include "mem/ruby/common/DataBlock.hh"
3711420Sdavid.guillen@arm.com#include "mem/ruby/common/Global.hh"
3811420Sdavid.guillen@arm.com#include "mem/ruby/common/SubBlock.hh"
3911420Sdavid.guillen@arm.com#include "mem/ruby/system/RubyPort.hh"
4011420Sdavid.guillen@arm.com#include "params/RubyTester.hh"
4111420Sdavid.guillen@arm.com
4211420Sdavid.guillen@arm.comclass RubyTester : public MemObject
4311420Sdavid.guillen@arm.com{
4411420Sdavid.guillen@arm.com  public:
4511420Sdavid.guillen@arm.com    class CpuPort : public SimpleTimingPort
4611420Sdavid.guillen@arm.com    {
4711800Sbrandon.potter@amd.com      private:
4811800Sbrandon.potter@amd.com        RubyTester *tester;
4911420Sdavid.guillen@arm.com
5011800Sbrandon.potter@amd.com      public:
5111800Sbrandon.potter@amd.com        CpuPort(const std::string &_name, RubyTester *_tester, int _idx)
5211420Sdavid.guillen@arm.com            : SimpleTimingPort(_name, _tester), tester(_tester), idx(_idx)
5311420Sdavid.guillen@arm.com        {}
5411420Sdavid.guillen@arm.com
5511420Sdavid.guillen@arm.com        int idx;
5611420Sdavid.guillen@arm.com
5711420Sdavid.guillen@arm.com      protected:
5811420Sdavid.guillen@arm.com        virtual bool recvTiming(PacketPtr pkt);
5911420Sdavid.guillen@arm.com        virtual Tick recvAtomic(PacketPtr pkt);
6011420Sdavid.guillen@arm.com    };
6111420Sdavid.guillen@arm.com
6211420Sdavid.guillen@arm.com    struct SenderState : public Packet::SenderState
6311420Sdavid.guillen@arm.com    {
6411420Sdavid.guillen@arm.com        SubBlock* subBlock;
6511420Sdavid.guillen@arm.com        Packet::SenderState *saved;
6611420Sdavid.guillen@arm.com
6711420Sdavid.guillen@arm.com        SenderState(Address addr, int size,
6811420Sdavid.guillen@arm.com                    Packet::SenderState *sender_state = NULL)
6911420Sdavid.guillen@arm.com            : saved(sender_state)
7011420Sdavid.guillen@arm.com        {
7111420Sdavid.guillen@arm.com            subBlock = new SubBlock(addr, size);
7211420Sdavid.guillen@arm.com        }
7311420Sdavid.guillen@arm.com
7411420Sdavid.guillen@arm.com        ~SenderState()
7511420Sdavid.guillen@arm.com        {
7611420Sdavid.guillen@arm.com            delete subBlock;
7711420Sdavid.guillen@arm.com        }
7811523Sdavid.guillen@arm.com    };
7911523Sdavid.guillen@arm.com
8011420Sdavid.guillen@arm.com    typedef RubyTesterParams Params;
8111420Sdavid.guillen@arm.com    RubyTester(const Params *p);
8211420Sdavid.guillen@arm.com    ~RubyTester();
8311420Sdavid.guillen@arm.com
8411420Sdavid.guillen@arm.com    virtual Port *getPort(const std::string &if_name, int idx = -1);
8511420Sdavid.guillen@arm.com
8611420Sdavid.guillen@arm.com    Port* getCpuPort(int idx);
8711420Sdavid.guillen@arm.com
8811420Sdavid.guillen@arm.com    virtual void init();
8911420Sdavid.guillen@arm.com
9011420Sdavid.guillen@arm.com    void wakeup();
9111420Sdavid.guillen@arm.com
9211420Sdavid.guillen@arm.com    void incrementCheckCompletions() { m_checks_completed++; }
9311420Sdavid.guillen@arm.com
9411420Sdavid.guillen@arm.com    void printStats(ostream& out) const {}
9511420Sdavid.guillen@arm.com    void clearStats() {}
9611420Sdavid.guillen@arm.com    void printConfig(ostream& out) const {}
9711420Sdavid.guillen@arm.com
9811420Sdavid.guillen@arm.com    void print(ostream& out) const;
9911420Sdavid.guillen@arm.com
10011420Sdavid.guillen@arm.com  protected:
10111420Sdavid.guillen@arm.com    class CheckStartEvent : public Event
10211420Sdavid.guillen@arm.com    {
10311420Sdavid.guillen@arm.com      private:
10411420Sdavid.guillen@arm.com        RubyTester *tester;
10511420Sdavid.guillen@arm.com
10611420Sdavid.guillen@arm.com      public:
10711420Sdavid.guillen@arm.com        CheckStartEvent(RubyTester *_tester)
10811420Sdavid.guillen@arm.com            : Event(CPU_Tick_Pri), tester(_tester)
10911420Sdavid.guillen@arm.com        {}
11011420Sdavid.guillen@arm.com        void process() { tester->wakeup(); }
11111420Sdavid.guillen@arm.com        virtual const char *description() const { return "RubyTester tick"; }
11211420Sdavid.guillen@arm.com    };
11311420Sdavid.guillen@arm.com
11411420Sdavid.guillen@arm.com    CheckStartEvent checkStartEvent;
11511420Sdavid.guillen@arm.com
11611528Sdavid.guillen@arm.com  private:
11711420Sdavid.guillen@arm.com    void hitCallback(NodeID proc, SubBlock* data);
11811528Sdavid.guillen@arm.com
11911420Sdavid.guillen@arm.com    void checkForDeadlock();
12011420Sdavid.guillen@arm.com
121    // Private copy constructor and assignment operator
122    RubyTester(const RubyTester& obj);
123    RubyTester& operator=(const RubyTester& obj);
124
125    CheckTable* m_checkTable_ptr;
126    Vector<Time> m_last_progress_vector;
127
128    uint64 m_checks_completed;
129    std::vector<CpuPort*> ports;
130    uint64 m_checks_to_complete;
131    int m_deadlock_threshold;
132    int m_num_cpu_sequencers;
133    int m_wakeup_frequency;
134};
135
136inline ostream&
137operator<<(ostream& out, const RubyTester& obj)
138{
139    obj.print(out);
140    out << flush;
141    return out;
142}
143
144#endif // __CPU_RUBYTEST_RUBYTESTER_HH__
145