clocked_object.hh revision 9418:9923a5ab8c13
111828Sjason@lowepower.com/*
210107Sradhika.jagtap@ARM.com * Copyright (c) 2012 ARM Limited
310107Sradhika.jagtap@ARM.com * All rights reserved
410107Sradhika.jagtap@ARM.com *
510107Sradhika.jagtap@ARM.com * The license below extends only to copyright in the software and shall
610107Sradhika.jagtap@ARM.com * not be construed as granting a license to any other intellectual
710107Sradhika.jagtap@ARM.com * property including but not limited to intellectual property relating
810107Sradhika.jagtap@ARM.com * to a hardware implementation of the functionality of the software
910107Sradhika.jagtap@ARM.com * licensed hereunder.  You may use the software subject to the license
1010107Sradhika.jagtap@ARM.com * terms below provided that you ensure that this notice is replicated
1110107Sradhika.jagtap@ARM.com * unmodified and in its entirety in all distributions of the software,
1210107Sradhika.jagtap@ARM.com * modified or unmodified, in source code or in binary form.
1310107Sradhika.jagtap@ARM.com *
1410107Sradhika.jagtap@ARM.com * Redistribution and use in source and binary forms, with or without
1510107Sradhika.jagtap@ARM.com * modification, are permitted provided that the following conditions are
1610107Sradhika.jagtap@ARM.com * met: redistributions of source code must retain the above copyright
1710107Sradhika.jagtap@ARM.com * notice, this list of conditions and the following disclaimer;
1810107Sradhika.jagtap@ARM.com * redistributions in binary form must reproduce the above copyright
1910107Sradhika.jagtap@ARM.com * notice, this list of conditions and the following disclaimer in the
2010107Sradhika.jagtap@ARM.com * documentation and/or other materials provided with the distribution;
2110107Sradhika.jagtap@ARM.com * neither the name of the copyright holders nor the names of its
2210107Sradhika.jagtap@ARM.com * contributors may be used to endorse or promote products derived from
2310107Sradhika.jagtap@ARM.com * this software without specific prior written permission.
2410107Sradhika.jagtap@ARM.com *
2510107Sradhika.jagtap@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610107Sradhika.jagtap@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710107Sradhika.jagtap@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810107Sradhika.jagtap@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910107Sradhika.jagtap@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010107Sradhika.jagtap@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110107Sradhika.jagtap@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210107Sradhika.jagtap@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310107Sradhika.jagtap@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410107Sradhika.jagtap@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510107Sradhika.jagtap@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610107Sradhika.jagtap@ARM.com *
3710107Sradhika.jagtap@ARM.com * Authors: Andreas Hansson
3810107Sradhika.jagtap@ARM.com */
3910107Sradhika.jagtap@ARM.com
4010107Sradhika.jagtap@ARM.com/**
4110107Sradhika.jagtap@ARM.com * @file
4210107Sradhika.jagtap@ARM.com * ClockedObject declaration and implementation.
4310107Sradhika.jagtap@ARM.com */
4410107Sradhika.jagtap@ARM.com
4510107Sradhika.jagtap@ARM.com#ifndef __SIM_CLOCKED_OBJECT_HH__
4610107Sradhika.jagtap@ARM.com#define __SIM_CLOCKED_OBJECT_HH__
4710107Sradhika.jagtap@ARM.com
4810107Sradhika.jagtap@ARM.com#include "base/intmath.hh"
4910107Sradhika.jagtap@ARM.com#include "base/misc.hh"
5010107Sradhika.jagtap@ARM.com#include "params/ClockedObject.hh"
5110107Sradhika.jagtap@ARM.com#include "sim/core.hh"
5210107Sradhika.jagtap@ARM.com#include "sim/sim_object.hh"
5310107Sradhika.jagtap@ARM.com
5410107Sradhika.jagtap@ARM.com/**
5510107Sradhika.jagtap@ARM.com * The ClockedObject class extends the SimObject with a clock and
5610107Sradhika.jagtap@ARM.com * accessor functions to relate ticks to the cycles of the object.
5710107Sradhika.jagtap@ARM.com */
5810107Sradhika.jagtap@ARM.comclass ClockedObject : public SimObject
5910107Sradhika.jagtap@ARM.com{
6010107Sradhika.jagtap@ARM.com
6110107Sradhika.jagtap@ARM.com  private:
6210107Sradhika.jagtap@ARM.com
6310107Sradhika.jagtap@ARM.com    // the tick value of the next clock edge (>= curTick()) at the
6410107Sradhika.jagtap@ARM.com    // time of the last call to update()
6510107Sradhika.jagtap@ARM.com    mutable Tick tick;
6610107Sradhika.jagtap@ARM.com
6710107Sradhika.jagtap@ARM.com    // The cycle counter value corresponding to the current value of
6810107Sradhika.jagtap@ARM.com    // 'tick'
6910107Sradhika.jagtap@ARM.com    mutable Cycles cycle;
7010107Sradhika.jagtap@ARM.com
7110107Sradhika.jagtap@ARM.com    /**
7210107Sradhika.jagtap@ARM.com     * Prevent inadvertent use of the copy constructor and assignment
7310107Sradhika.jagtap@ARM.com     * operator by making them private.
7410269Sradhika.jagtap@ARM.com     */
7510107Sradhika.jagtap@ARM.com    ClockedObject(ClockedObject&);
7610107Sradhika.jagtap@ARM.com    ClockedObject& operator=(ClockedObject&);
7710269Sradhika.jagtap@ARM.com
7810269Sradhika.jagtap@ARM.com    /**
7910269Sradhika.jagtap@ARM.com     *  Align cycle and tick to the next clock edge if not already done.
8010269Sradhika.jagtap@ARM.com     */
8110269Sradhika.jagtap@ARM.com    void update() const
8210269Sradhika.jagtap@ARM.com    {
8310269Sradhika.jagtap@ARM.com        // both tick and cycle are up-to-date and we are done, note
8410269Sradhika.jagtap@ARM.com        // that the >= is important as it captures cases where tick
8510269Sradhika.jagtap@ARM.com        // has already passed curTick()
8610269Sradhika.jagtap@ARM.com        if (tick >= curTick())
8710269Sradhika.jagtap@ARM.com            return;
8810269Sradhika.jagtap@ARM.com
8910269Sradhika.jagtap@ARM.com        // optimise for the common case and see if the tick should be
9010269Sradhika.jagtap@ARM.com        // advanced by a single clock period
9110269Sradhika.jagtap@ARM.com        tick += clock;
9210269Sradhika.jagtap@ARM.com        ++cycle;
9310269Sradhika.jagtap@ARM.com
9410269Sradhika.jagtap@ARM.com        // see if we are done at this point
9510269Sradhika.jagtap@ARM.com        if (tick >= curTick())
9610269Sradhika.jagtap@ARM.com            return;
9710269Sradhika.jagtap@ARM.com
9810269Sradhika.jagtap@ARM.com        // if not, we have to recalculate the cycle and tick, we
9910269Sradhika.jagtap@ARM.com        // perform the calculations in terms of relative cycles to
10010269Sradhika.jagtap@ARM.com        // allow changes to the clock period in the future
10112209Sgabeblack@google.com        Cycles elapsedCycles(divCeil(curTick() - tick, clock));
10210107Sradhika.jagtap@ARM.com        cycle += elapsedCycles;
10310107Sradhika.jagtap@ARM.com        tick += elapsedCycles * clock;
10410107Sradhika.jagtap@ARM.com    }
10510107Sradhika.jagtap@ARM.com
10610107Sradhika.jagtap@ARM.com  protected:
10710107Sradhika.jagtap@ARM.com
10810107Sradhika.jagtap@ARM.com    // Clock period in ticks
10910107Sradhika.jagtap@ARM.com    Tick clock;
11010107Sradhika.jagtap@ARM.com
11110107Sradhika.jagtap@ARM.com    /**
11210107Sradhika.jagtap@ARM.com     * Create a clocked object and set the clock based on the
11310107Sradhika.jagtap@ARM.com     * parameters.
11410107Sradhika.jagtap@ARM.com     */
11510107Sradhika.jagtap@ARM.com    ClockedObject(const ClockedObjectParams* p) :
11610107Sradhika.jagtap@ARM.com        SimObject(p), tick(0), cycle(0), clock(p->clock)
11710107Sradhika.jagtap@ARM.com    {
11810107Sradhika.jagtap@ARM.com        if (clock == 0) {
11910107Sradhika.jagtap@ARM.com            fatal("%s has a clock period of zero\n", name());
12010107Sradhika.jagtap@ARM.com        }
12110107Sradhika.jagtap@ARM.com    }
12210107Sradhika.jagtap@ARM.com
12310107Sradhika.jagtap@ARM.com    /**
12410107Sradhika.jagtap@ARM.com     * Virtual destructor due to inheritance.
12510107Sradhika.jagtap@ARM.com     */
12612208Sgabeblack@google.com    virtual ~ClockedObject() { }
12712208Sgabeblack@google.com
12812208Sgabeblack@google.com    /**
12912208Sgabeblack@google.com     * Reset the object's clock using the current global tick value. Likely
13010107Sradhika.jagtap@ARM.com     * to be used only when the global clock is reset. Currently, this done
13110107Sradhika.jagtap@ARM.com     * only when Ruby is done warming up the memory system.
13210107Sradhika.jagtap@ARM.com     */
13310107Sradhika.jagtap@ARM.com    void resetClock() const
13410107Sradhika.jagtap@ARM.com    {
13510107Sradhika.jagtap@ARM.com        Cycles elapsedCycles(divCeil(curTick(), clock));
13610107Sradhika.jagtap@ARM.com        cycle = elapsedCycles;
13712209Sgabeblack@google.com        tick = elapsedCycles * clock;
13810107Sradhika.jagtap@ARM.com    }
13910107Sradhika.jagtap@ARM.com
14010107Sradhika.jagtap@ARM.com  public:
14110107Sradhika.jagtap@ARM.com
14210107Sradhika.jagtap@ARM.com    /**
14310107Sradhika.jagtap@ARM.com     * Determine the tick when a cycle begins, by default the current
14410107Sradhika.jagtap@ARM.com     * one, but the argument also enables the caller to determine a
14510107Sradhika.jagtap@ARM.com     * future cycle.
14612209Sgabeblack@google.com     *
14710107Sradhika.jagtap@ARM.com     * @param cycles The number of cycles into the future
14810107Sradhika.jagtap@ARM.com     *
14910107Sradhika.jagtap@ARM.com     * @return The tick when the clock edge occurs
15010107Sradhika.jagtap@ARM.com     */
15110107Sradhika.jagtap@ARM.com    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
15210107Sradhika.jagtap@ARM.com    {
15310107Sradhika.jagtap@ARM.com        // align tick to the next clock edge
15410107Sradhika.jagtap@ARM.com        update();
15512210Sgabeblack@google.com
15610107Sradhika.jagtap@ARM.com        // figure out when this future cycle is
15710107Sradhika.jagtap@ARM.com        return tick + clock * cycles;
15810107Sradhika.jagtap@ARM.com    }
15910107Sradhika.jagtap@ARM.com
16010107Sradhika.jagtap@ARM.com    /**
16110107Sradhika.jagtap@ARM.com     * Determine the current cycle, corresponding to a tick aligned to
16210107Sradhika.jagtap@ARM.com     * a clock edge.
16310107Sradhika.jagtap@ARM.com     *
16410107Sradhika.jagtap@ARM.com     * @return The current cycle count
16512209Sgabeblack@google.com     */
16610107Sradhika.jagtap@ARM.com    inline Cycles curCycle() const
167    {
168        // align cycle to the next clock edge.
169        update();
170
171        return cycle;
172    }
173
174    /**
175     * Based on the clock of the object, determine the tick when the
176     * next cycle begins, in other words, return the next clock edge.
177     *
178     * @return The tick when the next cycle starts
179     */
180    Tick nextCycle() const
181    { return clockEdge(); }
182
183    inline uint64_t frequency() const { return SimClock::Frequency / clock; }
184
185    inline Tick clockPeriod() const { return clock; }
186
187    inline Cycles ticksToCycles(Tick tick) const
188    { return Cycles(tick / clock); }
189
190};
191
192#endif //__SIM_CLOCKED_OBJECT_HH__
193