tlm_quantumkeeper.h revision 13511
113511Sgabeblack@google.com/*****************************************************************************
213511Sgabeblack@google.com
313511Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
413511Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
513511Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
613511Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
713511Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
813511Sgabeblack@google.com  License.  You may obtain a copy of the License at
913511Sgabeblack@google.com
1013511Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1113511Sgabeblack@google.com
1213511Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1313511Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1413511Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1513511Sgabeblack@google.com  implied.  See the License for the specific language governing
1613511Sgabeblack@google.com  permissions and limitations under the License.
1713511Sgabeblack@google.com
1813511Sgabeblack@google.com *****************************************************************************/
1913511Sgabeblack@google.com
2013511Sgabeblack@google.com// 20-Mar-2009  John Aynsley  Add set_and_sync() method
2113511Sgabeblack@google.com
2213511Sgabeblack@google.com
2313511Sgabeblack@google.com#ifndef __TLM_QUANTUMKEEPER_H__
2413511Sgabeblack@google.com#define __TLM_QUANTUMKEEPER_H__
2513511Sgabeblack@google.com
2613511Sgabeblack@google.com#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h"
2713511Sgabeblack@google.com
2813511Sgabeblack@google.comnamespace tlm_utils {
2913511Sgabeblack@google.com
3013511Sgabeblack@google.com  //
3113511Sgabeblack@google.com  // tlm_quantumkeeper class
3213511Sgabeblack@google.com  //
3313511Sgabeblack@google.com  // The tlm_quantumkeeper class is used to keep track of the local time in
3413511Sgabeblack@google.com  // an initiator (how much it has run ahead of the SystemC time), to
3513511Sgabeblack@google.com  // synchronize with SystemC time etc.
3613511Sgabeblack@google.com  //
3713511Sgabeblack@google.com  class tlm_quantumkeeper
3813511Sgabeblack@google.com  {
3913511Sgabeblack@google.com  public:
4013511Sgabeblack@google.com    //
4113511Sgabeblack@google.com    // Static setters/getters for the global quantum value.
4213511Sgabeblack@google.com    //
4313511Sgabeblack@google.com    // The global quantum is the maximum time an initiator can run ahead of
4413511Sgabeblack@google.com    // systemC time. All initiators will synchronize on timingpoints that are
4513511Sgabeblack@google.com    // multiples of the global quantum value.
4613511Sgabeblack@google.com    //
4713511Sgabeblack@google.com    static void set_global_quantum(const sc_core::sc_time& t)
4813511Sgabeblack@google.com    {
4913511Sgabeblack@google.com      tlm::tlm_global_quantum::instance().set(t);
5013511Sgabeblack@google.com    }
5113511Sgabeblack@google.com
5213511Sgabeblack@google.com    static const sc_core::sc_time& get_global_quantum()
5313511Sgabeblack@google.com    {
5413511Sgabeblack@google.com      return tlm::tlm_global_quantum::instance().get();
5513511Sgabeblack@google.com    }
5613511Sgabeblack@google.com
5713511Sgabeblack@google.com  public:
5813511Sgabeblack@google.com    tlm_quantumkeeper() :
5913511Sgabeblack@google.com      m_next_sync_point(sc_core::SC_ZERO_TIME),
6013511Sgabeblack@google.com      m_local_time(sc_core::SC_ZERO_TIME)
6113511Sgabeblack@google.com    {
6213511Sgabeblack@google.com    }
6313511Sgabeblack@google.com
6413511Sgabeblack@google.com    virtual ~tlm_quantumkeeper() {}
6513511Sgabeblack@google.com
6613511Sgabeblack@google.com    //
6713511Sgabeblack@google.com    // Increment the local time (the time the initiator is ahead of the
6813511Sgabeblack@google.com    // systemC time) After incrementing the local time an initiator should
6913511Sgabeblack@google.com    // check (with the need_sync method) if a sync is required.
7013511Sgabeblack@google.com    //
7113511Sgabeblack@google.com    virtual void inc(const sc_core::sc_time& t)
7213511Sgabeblack@google.com    {
7313511Sgabeblack@google.com      m_local_time += t;
7413511Sgabeblack@google.com    }
7513511Sgabeblack@google.com
7613511Sgabeblack@google.com    //
7713511Sgabeblack@google.com    // Sets the local time (the time the initiator is ahead of the
7813511Sgabeblack@google.com    // systemC time) After changing the local time an initiator should
7913511Sgabeblack@google.com    // check (with the need_sync method) if a sync is required.
8013511Sgabeblack@google.com    //
8113511Sgabeblack@google.com    virtual void set(const sc_core::sc_time& t)
8213511Sgabeblack@google.com    {
8313511Sgabeblack@google.com      m_local_time = t;
8413511Sgabeblack@google.com    }
8513511Sgabeblack@google.com
8613511Sgabeblack@google.com    //
8713511Sgabeblack@google.com    // Checks if a sync to systemC is required for this initiator. This will
8813511Sgabeblack@google.com    // be the case if the local time becomes greater than the local (current)
8913511Sgabeblack@google.com    // quantum value for this initiator.
9013511Sgabeblack@google.com    //
9113511Sgabeblack@google.com    virtual bool need_sync() const
9213511Sgabeblack@google.com    {
9313511Sgabeblack@google.com      return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point;
9413511Sgabeblack@google.com    }
9513511Sgabeblack@google.com
9613511Sgabeblack@google.com    //
9713511Sgabeblack@google.com    // Synchronize to systemC. This call will do a wait for the time the
9813511Sgabeblack@google.com    // initiator was running ahead of systemC time and reset the
9913511Sgabeblack@google.com    // tlm_quantumkeeper.
10013511Sgabeblack@google.com    //
10113511Sgabeblack@google.com    virtual void sync()
10213511Sgabeblack@google.com    {
10313511Sgabeblack@google.com      sc_core::wait(m_local_time);
10413511Sgabeblack@google.com      reset();
10513511Sgabeblack@google.com    }
10613511Sgabeblack@google.com
10713511Sgabeblack@google.com    //
10813511Sgabeblack@google.com    // Non-virtual convenience method to set the local time and sync only if needed
10913511Sgabeblack@google.com    //
11013511Sgabeblack@google.com    void set_and_sync(const sc_core::sc_time& t)
11113511Sgabeblack@google.com    {
11213511Sgabeblack@google.com      set(t);
11313511Sgabeblack@google.com      if (need_sync())
11413511Sgabeblack@google.com        sync();
11513511Sgabeblack@google.com    }
11613511Sgabeblack@google.com
11713511Sgabeblack@google.com    //
11813511Sgabeblack@google.com    // Resets the local time to SC_ZERO_TIME and computes the value of the
11913511Sgabeblack@google.com    // next local quantum. This method should be called by an initiator after
12013511Sgabeblack@google.com    // a wait because of a synchronization request by a target (TLM_ACCEPTED,
12113511Sgabeblack@google.com    // or TLM_UPDATED).
12213511Sgabeblack@google.com    //
12313511Sgabeblack@google.com    virtual void reset()
12413511Sgabeblack@google.com    {
12513511Sgabeblack@google.com      m_local_time = sc_core::SC_ZERO_TIME;
12613511Sgabeblack@google.com      m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum();
12713511Sgabeblack@google.com    }
12813511Sgabeblack@google.com
12913511Sgabeblack@google.com    //
13013511Sgabeblack@google.com    // Helper function to get the current systemC time, taken the local time
13113511Sgabeblack@google.com    // into account. The current systemC time is calculated as the time
13213511Sgabeblack@google.com    // returned by sc_time_stamp incremeneted with the time the initiator is
13313511Sgabeblack@google.com    // running ahead.
13413511Sgabeblack@google.com    //
13513511Sgabeblack@google.com    virtual sc_core::sc_time get_current_time() const
13613511Sgabeblack@google.com    {
13713511Sgabeblack@google.com      return sc_core::sc_time_stamp() + m_local_time;
13813511Sgabeblack@google.com    }
13913511Sgabeblack@google.com
14013511Sgabeblack@google.com    //
14113511Sgabeblack@google.com    // Helper functions to get the time the initiator is running ahead of
14213511Sgabeblack@google.com    // systenC (local time). This time should be passed to a target in the
14313511Sgabeblack@google.com    // nb_transport call
14413511Sgabeblack@google.com    //
14513511Sgabeblack@google.com    virtual sc_core::sc_time get_local_time() const
14613511Sgabeblack@google.com    {
14713511Sgabeblack@google.com      return m_local_time;
14813511Sgabeblack@google.com    }
14913511Sgabeblack@google.com
15013511Sgabeblack@google.com  protected:
15113511Sgabeblack@google.com    //
15213511Sgabeblack@google.com    // Calculate the next local quantum for this initiator.
15313511Sgabeblack@google.com    //
15413511Sgabeblack@google.com    // The method can be overloaded in a derived object if an initiator wants
15513511Sgabeblack@google.com    // to use another local quantum. This derived object should also take the
15613511Sgabeblack@google.com    // global quantum into account. It's local quantum should not be set to a
15713511Sgabeblack@google.com    // value that is larger than the quantum returned by the
15813511Sgabeblack@google.com    // compute_local_quantum of the tlm_global_quantum singleton.
15913511Sgabeblack@google.com    //
16013511Sgabeblack@google.com    virtual sc_core::sc_time compute_local_quantum()
16113511Sgabeblack@google.com    {
16213511Sgabeblack@google.com      return tlm::tlm_global_quantum::instance().compute_local_quantum();
16313511Sgabeblack@google.com    }
16413511Sgabeblack@google.com
16513511Sgabeblack@google.com  protected:
16613511Sgabeblack@google.com    sc_core::sc_time m_next_sync_point;
16713511Sgabeblack@google.com    sc_core::sc_time m_local_time;
16813511Sgabeblack@google.com  };
16913511Sgabeblack@google.com
17013511Sgabeblack@google.com} // namespace tlm
17113511Sgabeblack@google.com
17213511Sgabeblack@google.com#endif
173