TLM-2.0: include/tlm/tlm_utils/tlm_quantumkeeper.h Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# include/tlm/tlm_utils/tlm_quantumkeeper.h

Go to the documentation of this file.

    00001 /*****************************************************************************
    00002
    00003   The following code is derived, directly or indirectly, from the SystemC
    00004   source code Copyright (c) 1996-2008 by all Contributors.
    00005   All Rights reserved.
    00006
    00007   The contents of this file are subject to the restrictions and limitations
    00008   set forth in the SystemC Open Source License Version 3.0 (the "License");
    00009   You may not use this file except in compliance with such restrictions and
    00010   limitations. You may obtain instructions on how to receive a copy of the
    00011   License at http://www.systemc.org/. Software distributed by Contributors
    00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
    00013   ANY KIND, either express or implied. See the License for the specific
    00014   language governing rights and limitations under the License.
    00015
    00016  *****************************************************************************/
    00017
    00018 // 20-Mar-2009  John Aynsley  Add set_and_sync() method
    00019
    00020
    00021 #ifndef __TLM_QUANTUMKEEPER_H__
    00022 #define __TLM_QUANTUMKEEPER_H__
    00023
    00024 #include "tlm_h/tlm_quantum/tlm_global_quantum.h"
    00025
    00026 namespace tlm_utils {
    00027
    00028   //
    00029   // tlm_quantumkeeper class
    00030   //
    00031   // The tlm_quantumkeeper class is used to keep track of the local time in
    00032   // an initiator (how much it has run ahead of the SystemC time), to
    00033   // synchronize with SystemC time etc.
    00034   //
    00035   class tlm_quantumkeeper
    00036   {
    00037   public:
    00038     //
    00039     // Static setters/getters for the global quantum value.
    00040     //
    00041     // The global quantum is the maximum time an initiator can run ahead of
    00042     // systemC time. All initiators will synchronize on timingpoints that are
    00043     // multiples of the global quantum value.
    00044     //
    00045     static void set_global_quantum(const sc_core::sc_time& t)
    00046     {
    00047       tlm::tlm_global_quantum::instance().set(t);
    00048     }
    00049
    00050     static const sc_core::sc_time& get_global_quantum()
    00051     {
    00052       return tlm::tlm_global_quantum::instance().get();
    00053     }
    00054
    00055   public:
    00056     tlm_quantumkeeper() :
    00057       m_next_sync_point(sc_core::SC_ZERO_TIME),
    00058       m_local_time(sc_core::SC_ZERO_TIME)
    00059     {
    00060     }
    00061
    00062     virtual ~tlm_quantumkeeper() {}
    00063
    00064     //
    00065     // Increment the local time (the time the initiator is ahead of the
    00066     // systemC time) After incrementing the local time an initiator should
    00067     // check (with the need_sync method) if a sync is required.
    00068     //
    00069     virtual void inc(const sc_core::sc_time& t)
    00070     {
    00071       m_local_time += t;
    00072     }
    00073
    00074     //
    00075     // Sets the local time (the time the initiator is ahead of the
    00076     // systemC time) After changing the local time an initiator should
    00077     // check (with the need_sync method) if a sync is required.
    00078     //
    00079     virtual void set(const sc_core::sc_time& t)
    00080     {
    00081       m_local_time = t;
    00082     }
    00083
    00084     //
    00085     // Checks if a sync to systemC is required for this initiator. This will
    00086     // be the case if the local time becomes greater than the local (current)
    00087     // quantum value for this initiator.
    00088     //
    00089     virtual bool need_sync() const
    00090     {
    00091       return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point;
    00092     }
    00093
    00094     //
    00095     // Synchronize to systemC. This call will do a wait for the time the
    00096     // initiator was running ahead of systemC time and reset the
    00097     // tlm_quantumkeeper.
    00098     //
    00099     virtual void sync()
    00100     {
    00101       sc_core::wait(m_local_time);
    00102       reset();
    00103     }
    00104
    00105     //
    00106     // Non-virtual convenience method to set the local time and sync only if needed
    00107     //
    00108     void set_and_sync(const sc_core::sc_time& t)
    00109     {
    00110       set(t);
    00111       if (need_sync())
    00112         sync();
    00113     }
    00114
    00115     //
    00116     // Resets the local time to SC_ZERO_TIME and computes the value of the
    00117     // next local quantum. This method should be called by an initiator after
    00118     // a wait because of a synchronization request by a target (TLM_ACCEPTED,
    00119     // or TLM_UPDATED).
    00120     //
    00121     virtual void reset()
    00122     {
    00123       m_local_time = sc_core::SC_ZERO_TIME;
    00124       m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum();
    00125     }
    00126
    00127     //
    00128     // Helper function to get the current systemC time, taken the local time
    00129     // into account. The current systemC time is calculated as the time
    00130     // returned by sc_time_stamp incremeneted with the time the initiator is
    00131     // running ahead.
    00132     //
    00133     virtual sc_core::sc_time get_current_time() const
    00134     {
    00135       return sc_core::sc_time_stamp() + m_local_time;
    00136     }
    00137
    00138     //
    00139     // Helper functions to get the time the initiator is running ahead of
    00140     // systenC (local time). This time should be passed to a target in the
    00141     // nb_transport call
    00142     //
    00143     virtual sc_core::sc_time get_local_time() const
    00144     {
    00145       return m_local_time;
    00146     }
    00147
    00148   protected:
    00149     //
    00150     // Calculate the next local quantum for this initiator.
    00151     //
    00152     // The method can be overloaded in a derived object if an initiator wants
    00153     // to use another local quantum. This derived object should also take the
    00154     // global quantum into account. It's local quantum should not be set to a
    00155     // value that is larger than the quantum returned by the
    00156     // compute_local_quantum of the tlm_global_quantum singleton.
    00157     //
    00158     virtual sc_core::sc_time compute_local_quantum()
    00159     {
    00160       return tlm::tlm_global_quantum::instance().compute_local_quantum();
    00161     }
    00162
    00163   protected:
    00164     sc_core::sc_time m_next_sync_point;
    00165     sc_core::sc_time m_local_time;
    00166   };
    00167
    00168 } // namespace tlm
    00169
    00170 #endif