112027Sjungma@eit.uni-kl.de/*****************************************************************************
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412027Sjungma@eit.uni-kl.de  more contributor license agreements.  See the NOTICE file distributed
512027Sjungma@eit.uni-kl.de  with this work for additional information regarding copyright ownership.
612027Sjungma@eit.uni-kl.de  Accellera licenses this file to you under the Apache License, Version 2.0
712027Sjungma@eit.uni-kl.de  (the "License"); you may not use this file except in compliance with the
812027Sjungma@eit.uni-kl.de  License.  You may obtain a copy of the License at
912027Sjungma@eit.uni-kl.de
1012027Sjungma@eit.uni-kl.de    http://www.apache.org/licenses/LICENSE-2.0
1112027Sjungma@eit.uni-kl.de
1212027Sjungma@eit.uni-kl.de  Unless required by applicable law or agreed to in writing, software
1312027Sjungma@eit.uni-kl.de  distributed under the License is distributed on an "AS IS" BASIS,
1412027Sjungma@eit.uni-kl.de  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512027Sjungma@eit.uni-kl.de  implied.  See the License for the specific language governing
1612027Sjungma@eit.uni-kl.de  permissions and limitations under the License.
1712027Sjungma@eit.uni-kl.de
1812027Sjungma@eit.uni-kl.de *****************************************************************************/
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de// 20-Mar-2009  John Aynsley  Add set_and_sync() method
2112027Sjungma@eit.uni-kl.de
2212027Sjungma@eit.uni-kl.de
2312027Sjungma@eit.uni-kl.de#ifndef __TLM_QUANTUMKEEPER_H__
2412027Sjungma@eit.uni-kl.de#define __TLM_QUANTUMKEEPER_H__
2512027Sjungma@eit.uni-kl.de
2612027Sjungma@eit.uni-kl.de#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h"
2712027Sjungma@eit.uni-kl.de
2812027Sjungma@eit.uni-kl.denamespace tlm_utils {
2912027Sjungma@eit.uni-kl.de
3012027Sjungma@eit.uni-kl.de  //
3112027Sjungma@eit.uni-kl.de  // tlm_quantumkeeper class
3212027Sjungma@eit.uni-kl.de  //
3312027Sjungma@eit.uni-kl.de  // The tlm_quantumkeeper class is used to keep track of the local time in
3412027Sjungma@eit.uni-kl.de  // an initiator (how much it has run ahead of the SystemC time), to
3512027Sjungma@eit.uni-kl.de  // synchronize with SystemC time etc.
3612027Sjungma@eit.uni-kl.de  //
3712027Sjungma@eit.uni-kl.de  class tlm_quantumkeeper
3812027Sjungma@eit.uni-kl.de  {
3912027Sjungma@eit.uni-kl.de  public:
4012027Sjungma@eit.uni-kl.de    //
4112027Sjungma@eit.uni-kl.de    // Static setters/getters for the global quantum value.
4212027Sjungma@eit.uni-kl.de    //
4312027Sjungma@eit.uni-kl.de    // The global quantum is the maximum time an initiator can run ahead of
4412027Sjungma@eit.uni-kl.de    // systemC time. All initiators will synchronize on timingpoints that are
4512027Sjungma@eit.uni-kl.de    // multiples of the global quantum value.
4612027Sjungma@eit.uni-kl.de    //
4712027Sjungma@eit.uni-kl.de    static void set_global_quantum(const sc_core::sc_time& t)
4812027Sjungma@eit.uni-kl.de    {
4912027Sjungma@eit.uni-kl.de      tlm::tlm_global_quantum::instance().set(t);
5012027Sjungma@eit.uni-kl.de    }
5112027Sjungma@eit.uni-kl.de
5212027Sjungma@eit.uni-kl.de    static const sc_core::sc_time& get_global_quantum()
5312027Sjungma@eit.uni-kl.de    {
5412027Sjungma@eit.uni-kl.de      return tlm::tlm_global_quantum::instance().get();
5512027Sjungma@eit.uni-kl.de    }
5612027Sjungma@eit.uni-kl.de
5712027Sjungma@eit.uni-kl.de  public:
5812027Sjungma@eit.uni-kl.de    tlm_quantumkeeper() :
5912027Sjungma@eit.uni-kl.de      m_next_sync_point(sc_core::SC_ZERO_TIME),
6012027Sjungma@eit.uni-kl.de      m_local_time(sc_core::SC_ZERO_TIME)
6112027Sjungma@eit.uni-kl.de    {
6212027Sjungma@eit.uni-kl.de    }
6312027Sjungma@eit.uni-kl.de
6412027Sjungma@eit.uni-kl.de    virtual ~tlm_quantumkeeper() {}
6512027Sjungma@eit.uni-kl.de
6612027Sjungma@eit.uni-kl.de    //
6712027Sjungma@eit.uni-kl.de    // Increment the local time (the time the initiator is ahead of the
6812027Sjungma@eit.uni-kl.de    // systemC time) After incrementing the local time an initiator should
6912027Sjungma@eit.uni-kl.de    // check (with the need_sync method) if a sync is required.
7012027Sjungma@eit.uni-kl.de    //
7112027Sjungma@eit.uni-kl.de    virtual void inc(const sc_core::sc_time& t)
7212027Sjungma@eit.uni-kl.de    {
7312027Sjungma@eit.uni-kl.de      m_local_time += t;
7412027Sjungma@eit.uni-kl.de    }
7512027Sjungma@eit.uni-kl.de
7612027Sjungma@eit.uni-kl.de    //
7712027Sjungma@eit.uni-kl.de    // Sets the local time (the time the initiator is ahead of the
7812027Sjungma@eit.uni-kl.de    // systemC time) After changing the local time an initiator should
7912027Sjungma@eit.uni-kl.de    // check (with the need_sync method) if a sync is required.
8012027Sjungma@eit.uni-kl.de    //
8112027Sjungma@eit.uni-kl.de    virtual void set(const sc_core::sc_time& t)
8212027Sjungma@eit.uni-kl.de    {
8312027Sjungma@eit.uni-kl.de      m_local_time = t;
8412027Sjungma@eit.uni-kl.de    }
8512027Sjungma@eit.uni-kl.de
8612027Sjungma@eit.uni-kl.de    //
8712027Sjungma@eit.uni-kl.de    // Checks if a sync to systemC is required for this initiator. This will
8812027Sjungma@eit.uni-kl.de    // be the case if the local time becomes greater than the local (current)
8912027Sjungma@eit.uni-kl.de    // quantum value for this initiator.
9012027Sjungma@eit.uni-kl.de    //
9112027Sjungma@eit.uni-kl.de    virtual bool need_sync() const
9212027Sjungma@eit.uni-kl.de    {
9312027Sjungma@eit.uni-kl.de      return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point;
9412027Sjungma@eit.uni-kl.de    }
9512027Sjungma@eit.uni-kl.de
9612027Sjungma@eit.uni-kl.de    //
9712027Sjungma@eit.uni-kl.de    // Synchronize to systemC. This call will do a wait for the time the
9812027Sjungma@eit.uni-kl.de    // initiator was running ahead of systemC time and reset the
9912027Sjungma@eit.uni-kl.de    // tlm_quantumkeeper.
10012027Sjungma@eit.uni-kl.de    //
10112027Sjungma@eit.uni-kl.de    virtual void sync()
10212027Sjungma@eit.uni-kl.de    {
10312027Sjungma@eit.uni-kl.de      sc_core::wait(m_local_time);
10412027Sjungma@eit.uni-kl.de      reset();
10512027Sjungma@eit.uni-kl.de    }
10612027Sjungma@eit.uni-kl.de
10712027Sjungma@eit.uni-kl.de    //
10812027Sjungma@eit.uni-kl.de    // Non-virtual convenience method to set the local time and sync only if needed
10912027Sjungma@eit.uni-kl.de    //
11012027Sjungma@eit.uni-kl.de    void set_and_sync(const sc_core::sc_time& t)
11112027Sjungma@eit.uni-kl.de    {
11212027Sjungma@eit.uni-kl.de      set(t);
11312027Sjungma@eit.uni-kl.de      if (need_sync())
11412027Sjungma@eit.uni-kl.de        sync();
11512027Sjungma@eit.uni-kl.de    }
11612027Sjungma@eit.uni-kl.de
11712027Sjungma@eit.uni-kl.de    //
11812027Sjungma@eit.uni-kl.de    // Resets the local time to SC_ZERO_TIME and computes the value of the
11912027Sjungma@eit.uni-kl.de    // next local quantum. This method should be called by an initiator after
12012027Sjungma@eit.uni-kl.de    // a wait because of a synchronization request by a target (TLM_ACCEPTED,
12112027Sjungma@eit.uni-kl.de    // or TLM_UPDATED).
12212027Sjungma@eit.uni-kl.de    //
12312027Sjungma@eit.uni-kl.de    virtual void reset()
12412027Sjungma@eit.uni-kl.de    {
12512027Sjungma@eit.uni-kl.de      m_local_time = sc_core::SC_ZERO_TIME;
12612027Sjungma@eit.uni-kl.de      m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum();
12712027Sjungma@eit.uni-kl.de    }
12812027Sjungma@eit.uni-kl.de
12912027Sjungma@eit.uni-kl.de    //
13012027Sjungma@eit.uni-kl.de    // Helper function to get the current systemC time, taken the local time
13112027Sjungma@eit.uni-kl.de    // into account. The current systemC time is calculated as the time
13212027Sjungma@eit.uni-kl.de    // returned by sc_time_stamp incremeneted with the time the initiator is
13312027Sjungma@eit.uni-kl.de    // running ahead.
13412027Sjungma@eit.uni-kl.de    //
13512027Sjungma@eit.uni-kl.de    virtual sc_core::sc_time get_current_time() const
13612027Sjungma@eit.uni-kl.de    {
13712027Sjungma@eit.uni-kl.de      return sc_core::sc_time_stamp() + m_local_time;
13812027Sjungma@eit.uni-kl.de    }
13912027Sjungma@eit.uni-kl.de
14012027Sjungma@eit.uni-kl.de    //
14112027Sjungma@eit.uni-kl.de    // Helper functions to get the time the initiator is running ahead of
14212027Sjungma@eit.uni-kl.de    // systenC (local time). This time should be passed to a target in the
14312027Sjungma@eit.uni-kl.de    // nb_transport call
14412027Sjungma@eit.uni-kl.de    //
14512027Sjungma@eit.uni-kl.de    virtual sc_core::sc_time get_local_time() const
14612027Sjungma@eit.uni-kl.de    {
14712027Sjungma@eit.uni-kl.de      return m_local_time;
14812027Sjungma@eit.uni-kl.de    }
14912027Sjungma@eit.uni-kl.de
15012027Sjungma@eit.uni-kl.de  protected:
15112027Sjungma@eit.uni-kl.de    //
15212027Sjungma@eit.uni-kl.de    // Calculate the next local quantum for this initiator.
15312027Sjungma@eit.uni-kl.de    //
15412027Sjungma@eit.uni-kl.de    // The method can be overloaded in a derived object if an initiator wants
15512027Sjungma@eit.uni-kl.de    // to use another local quantum. This derived object should also take the
15612027Sjungma@eit.uni-kl.de    // global quantum into account. It's local quantum should not be set to a
15712027Sjungma@eit.uni-kl.de    // value that is larger than the quantum returned by the
15812027Sjungma@eit.uni-kl.de    // compute_local_quantum of the tlm_global_quantum singleton.
15912027Sjungma@eit.uni-kl.de    //
16012027Sjungma@eit.uni-kl.de    virtual sc_core::sc_time compute_local_quantum()
16112027Sjungma@eit.uni-kl.de    {
16212027Sjungma@eit.uni-kl.de      return tlm::tlm_global_quantum::instance().compute_local_quantum();
16312027Sjungma@eit.uni-kl.de    }
16412027Sjungma@eit.uni-kl.de
16512027Sjungma@eit.uni-kl.de  protected:
16612027Sjungma@eit.uni-kl.de    sc_core::sc_time m_next_sync_point;
16712027Sjungma@eit.uni-kl.de    sc_core::sc_time m_local_time;
16812027Sjungma@eit.uni-kl.de  };
16912027Sjungma@eit.uni-kl.de
17012027Sjungma@eit.uni-kl.de} // namespace tlm
17112027Sjungma@eit.uni-kl.de
17212027Sjungma@eit.uni-kl.de#endif
173