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