tlm_quantumkeeper.h revision 13513
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 2013513Sgabeblack@google.com#ifndef __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ 2113513Sgabeblack@google.com#define __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ 2213511Sgabeblack@google.com 2313511Sgabeblack@google.com#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h" 2413511Sgabeblack@google.com 2513513Sgabeblack@google.comnamespace tlm_utils 2613513Sgabeblack@google.com{ 2713511Sgabeblack@google.com 2813513Sgabeblack@google.com// tlm_quantumkeeper class 2913513Sgabeblack@google.com// 3013513Sgabeblack@google.com// The tlm_quantumkeeper class is used to keep track of the local time in 3113513Sgabeblack@google.com// an initiator (how much it has run ahead of the SystemC time), to 3213513Sgabeblack@google.com// synchronize with SystemC time etc. 3313513Sgabeblack@google.comclass tlm_quantumkeeper 3413513Sgabeblack@google.com{ 3513511Sgabeblack@google.com public: 3613511Sgabeblack@google.com // 3713511Sgabeblack@google.com // Static setters/getters for the global quantum value. 3813511Sgabeblack@google.com // 3913511Sgabeblack@google.com // The global quantum is the maximum time an initiator can run ahead of 4013513Sgabeblack@google.com // SystemC time. All initiators will synchronize on timing points that are 4113511Sgabeblack@google.com // multiples of the global quantum value. 4213511Sgabeblack@google.com // 4313513Sgabeblack@google.com static void 4413513Sgabeblack@google.com set_global_quantum(const sc_core::sc_time &t) 4513511Sgabeblack@google.com { 4613513Sgabeblack@google.com tlm::tlm_global_quantum::instance().set(t); 4713511Sgabeblack@google.com } 4813511Sgabeblack@google.com 4913513Sgabeblack@google.com static const sc_core::sc_time & 5013513Sgabeblack@google.com get_global_quantum() 5113511Sgabeblack@google.com { 5213513Sgabeblack@google.com return tlm::tlm_global_quantum::instance().get(); 5313511Sgabeblack@google.com } 5413511Sgabeblack@google.com 5513511Sgabeblack@google.com public: 5613513Sgabeblack@google.com tlm_quantumkeeper() : m_next_sync_point(sc_core::SC_ZERO_TIME), 5713513Sgabeblack@google.com m_local_time(sc_core::SC_ZERO_TIME) 5813513Sgabeblack@google.com {} 5913511Sgabeblack@google.com 6013511Sgabeblack@google.com virtual ~tlm_quantumkeeper() {} 6113511Sgabeblack@google.com 6213511Sgabeblack@google.com // Increment the local time (the time the initiator is ahead of the 6313511Sgabeblack@google.com // systemC time) After incrementing the local time an initiator should 6413511Sgabeblack@google.com // check (with the need_sync method) if a sync is required. 6513513Sgabeblack@google.com virtual void inc(const sc_core::sc_time &t) { m_local_time += t; } 6613511Sgabeblack@google.com 6713511Sgabeblack@google.com // Sets the local time (the time the initiator is ahead of the 6813511Sgabeblack@google.com // systemC time) After changing the local time an initiator should 6913511Sgabeblack@google.com // check (with the need_sync method) if a sync is required. 7013513Sgabeblack@google.com virtual void set(const sc_core::sc_time &t) { m_local_time = t; } 7113511Sgabeblack@google.com 7213511Sgabeblack@google.com // Checks if a sync to systemC is required for this initiator. This will 7313511Sgabeblack@google.com // be the case if the local time becomes greater than the local (current) 7413511Sgabeblack@google.com // quantum value for this initiator. 7513513Sgabeblack@google.com virtual bool 7613513Sgabeblack@google.com need_sync() const 7713511Sgabeblack@google.com { 7813513Sgabeblack@google.com return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point; 7913511Sgabeblack@google.com } 8013511Sgabeblack@google.com 8113511Sgabeblack@google.com // Synchronize to systemC. This call will do a wait for the time the 8213511Sgabeblack@google.com // initiator was running ahead of systemC time and reset the 8313511Sgabeblack@google.com // tlm_quantumkeeper. 8413513Sgabeblack@google.com virtual void 8513513Sgabeblack@google.com sync() 8613511Sgabeblack@google.com { 8713513Sgabeblack@google.com sc_core::wait(m_local_time); 8813513Sgabeblack@google.com reset(); 8913511Sgabeblack@google.com } 9013511Sgabeblack@google.com 9113513Sgabeblack@google.com // Non-virtual convenience method to set the local time and sync only if 9213513Sgabeblack@google.com // needed 9313513Sgabeblack@google.com void 9413513Sgabeblack@google.com set_and_sync(const sc_core::sc_time &t) 9513511Sgabeblack@google.com { 9613513Sgabeblack@google.com set(t); 9713513Sgabeblack@google.com if (need_sync()) 9813513Sgabeblack@google.com sync(); 9913511Sgabeblack@google.com } 10013511Sgabeblack@google.com 10113511Sgabeblack@google.com // Resets the local time to SC_ZERO_TIME and computes the value of the 10213511Sgabeblack@google.com // next local quantum. This method should be called by an initiator after 10313511Sgabeblack@google.com // a wait because of a synchronization request by a target (TLM_ACCEPTED, 10413511Sgabeblack@google.com // or TLM_UPDATED). 10513513Sgabeblack@google.com virtual void 10613513Sgabeblack@google.com reset() 10713511Sgabeblack@google.com { 10813513Sgabeblack@google.com m_local_time = sc_core::SC_ZERO_TIME; 10913513Sgabeblack@google.com m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum(); 11013511Sgabeblack@google.com } 11113511Sgabeblack@google.com 11213511Sgabeblack@google.com // Helper function to get the current systemC time, taken the local time 11313511Sgabeblack@google.com // into account. The current systemC time is calculated as the time 11413511Sgabeblack@google.com // returned by sc_time_stamp incremeneted with the time the initiator is 11513511Sgabeblack@google.com // running ahead. 11613513Sgabeblack@google.com virtual sc_core::sc_time 11713513Sgabeblack@google.com get_current_time() const 11813511Sgabeblack@google.com { 11913513Sgabeblack@google.com return sc_core::sc_time_stamp() + m_local_time; 12013511Sgabeblack@google.com } 12113511Sgabeblack@google.com 12213511Sgabeblack@google.com // Helper functions to get the time the initiator is running ahead of 12313511Sgabeblack@google.com // systenC (local time). This time should be passed to a target in the 12413511Sgabeblack@google.com // nb_transport call 12513513Sgabeblack@google.com virtual sc_core::sc_time 12613513Sgabeblack@google.com get_local_time() const 12713511Sgabeblack@google.com { 12813513Sgabeblack@google.com return m_local_time; 12913511Sgabeblack@google.com } 13013511Sgabeblack@google.com 13113511Sgabeblack@google.com protected: 13213511Sgabeblack@google.com // Calculate the next local quantum for this initiator. 13313511Sgabeblack@google.com // 13413511Sgabeblack@google.com // The method can be overloaded in a derived object if an initiator wants 13513511Sgabeblack@google.com // to use another local quantum. This derived object should also take the 13613511Sgabeblack@google.com // global quantum into account. It's local quantum should not be set to a 13713511Sgabeblack@google.com // value that is larger than the quantum returned by the 13813511Sgabeblack@google.com // compute_local_quantum of the tlm_global_quantum singleton. 13913513Sgabeblack@google.com virtual sc_core::sc_time 14013513Sgabeblack@google.com compute_local_quantum() 14113511Sgabeblack@google.com { 14213513Sgabeblack@google.com return tlm::tlm_global_quantum::instance().compute_local_quantum(); 14313511Sgabeblack@google.com } 14413511Sgabeblack@google.com 14513511Sgabeblack@google.com protected: 14613511Sgabeblack@google.com sc_core::sc_time m_next_sync_point; 14713511Sgabeblack@google.com sc_core::sc_time m_local_time; 14813513Sgabeblack@google.com}; 14913511Sgabeblack@google.com 15013513Sgabeblack@google.com} // namespace tlm_utils 15113511Sgabeblack@google.com 15213513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ */ 153