tlm_quantumkeeper.h revision 13513
1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20#ifndef __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ 21#define __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ 22 23#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h" 24 25namespace tlm_utils 26{ 27 28// tlm_quantumkeeper class 29// 30// The tlm_quantumkeeper class is used to keep track of the local time in 31// an initiator (how much it has run ahead of the SystemC time), to 32// synchronize with SystemC time etc. 33class tlm_quantumkeeper 34{ 35 public: 36 // 37 // Static setters/getters for the global quantum value. 38 // 39 // The global quantum is the maximum time an initiator can run ahead of 40 // SystemC time. All initiators will synchronize on timing points that are 41 // multiples of the global quantum value. 42 // 43 static void 44 set_global_quantum(const sc_core::sc_time &t) 45 { 46 tlm::tlm_global_quantum::instance().set(t); 47 } 48 49 static const sc_core::sc_time & 50 get_global_quantum() 51 { 52 return tlm::tlm_global_quantum::instance().get(); 53 } 54 55 public: 56 tlm_quantumkeeper() : m_next_sync_point(sc_core::SC_ZERO_TIME), 57 m_local_time(sc_core::SC_ZERO_TIME) 58 {} 59 60 virtual ~tlm_quantumkeeper() {} 61 62 // Increment the local time (the time the initiator is ahead of the 63 // systemC time) After incrementing the local time an initiator should 64 // check (with the need_sync method) if a sync is required. 65 virtual void inc(const sc_core::sc_time &t) { m_local_time += t; } 66 67 // Sets the local time (the time the initiator is ahead of the 68 // systemC time) After changing the local time an initiator should 69 // check (with the need_sync method) if a sync is required. 70 virtual void set(const sc_core::sc_time &t) { m_local_time = t; } 71 72 // Checks if a sync to systemC is required for this initiator. This will 73 // be the case if the local time becomes greater than the local (current) 74 // quantum value for this initiator. 75 virtual bool 76 need_sync() const 77 { 78 return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point; 79 } 80 81 // Synchronize to systemC. This call will do a wait for the time the 82 // initiator was running ahead of systemC time and reset the 83 // tlm_quantumkeeper. 84 virtual void 85 sync() 86 { 87 sc_core::wait(m_local_time); 88 reset(); 89 } 90 91 // Non-virtual convenience method to set the local time and sync only if 92 // needed 93 void 94 set_and_sync(const sc_core::sc_time &t) 95 { 96 set(t); 97 if (need_sync()) 98 sync(); 99 } 100 101 // Resets the local time to SC_ZERO_TIME and computes the value of the 102 // next local quantum. This method should be called by an initiator after 103 // a wait because of a synchronization request by a target (TLM_ACCEPTED, 104 // or TLM_UPDATED). 105 virtual void 106 reset() 107 { 108 m_local_time = sc_core::SC_ZERO_TIME; 109 m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum(); 110 } 111 112 // Helper function to get the current systemC time, taken the local time 113 // into account. The current systemC time is calculated as the time 114 // returned by sc_time_stamp incremeneted with the time the initiator is 115 // running ahead. 116 virtual sc_core::sc_time 117 get_current_time() const 118 { 119 return sc_core::sc_time_stamp() + m_local_time; 120 } 121 122 // Helper functions to get the time the initiator is running ahead of 123 // systenC (local time). This time should be passed to a target in the 124 // nb_transport call 125 virtual sc_core::sc_time 126 get_local_time() const 127 { 128 return m_local_time; 129 } 130 131 protected: 132 // Calculate the next local quantum for this initiator. 133 // 134 // The method can be overloaded in a derived object if an initiator wants 135 // to use another local quantum. This derived object should also take the 136 // global quantum into account. It's local quantum should not be set to a 137 // value that is larger than the quantum returned by the 138 // compute_local_quantum of the tlm_global_quantum singleton. 139 virtual sc_core::sc_time 140 compute_local_quantum() 141 { 142 return tlm::tlm_global_quantum::instance().compute_local_quantum(); 143 } 144 145 protected: 146 sc_core::sc_time m_next_sync_point; 147 sc_core::sc_time m_local_time; 148}; 149 150} // namespace tlm_utils 151 152#endif /* __SYSTEMC_EXT_TLM_UTILS_TLM_QUANTUMKEEPER_H__ */ 153