tlm_quantumkeeper.h revision 13511
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// 20-Mar-2009 John Aynsley Add set_and_sync() method 21 22 23#ifndef __TLM_QUANTUMKEEPER_H__ 24#define __TLM_QUANTUMKEEPER_H__ 25 26#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h" 27 28namespace tlm_utils { 29 30 // 31 // tlm_quantumkeeper class 32 // 33 // The tlm_quantumkeeper class is used to keep track of the local time in 34 // an initiator (how much it has run ahead of the SystemC time), to 35 // synchronize with SystemC time etc. 36 // 37 class tlm_quantumkeeper 38 { 39 public: 40 // 41 // Static setters/getters for the global quantum value. 42 // 43 // The global quantum is the maximum time an initiator can run ahead of 44 // systemC time. All initiators will synchronize on timingpoints that are 45 // multiples of the global quantum value. 46 // 47 static void set_global_quantum(const sc_core::sc_time& t) 48 { 49 tlm::tlm_global_quantum::instance().set(t); 50 } 51 52 static const sc_core::sc_time& get_global_quantum() 53 { 54 return tlm::tlm_global_quantum::instance().get(); 55 } 56 57 public: 58 tlm_quantumkeeper() : 59 m_next_sync_point(sc_core::SC_ZERO_TIME), 60 m_local_time(sc_core::SC_ZERO_TIME) 61 { 62 } 63 64 virtual ~tlm_quantumkeeper() {} 65 66 // 67 // Increment the local time (the time the initiator is ahead of the 68 // systemC time) After incrementing the local time an initiator should 69 // check (with the need_sync method) if a sync is required. 70 // 71 virtual void inc(const sc_core::sc_time& t) 72 { 73 m_local_time += t; 74 } 75 76 // 77 // Sets the local time (the time the initiator is ahead of the 78 // systemC time) After changing the local time an initiator should 79 // check (with the need_sync method) if a sync is required. 80 // 81 virtual void set(const sc_core::sc_time& t) 82 { 83 m_local_time = t; 84 } 85 86 // 87 // Checks if a sync to systemC is required for this initiator. This will 88 // be the case if the local time becomes greater than the local (current) 89 // quantum value for this initiator. 90 // 91 virtual bool need_sync() const 92 { 93 return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point; 94 } 95 96 // 97 // Synchronize to systemC. This call will do a wait for the time the 98 // initiator was running ahead of systemC time and reset the 99 // tlm_quantumkeeper. 100 // 101 virtual void sync() 102 { 103 sc_core::wait(m_local_time); 104 reset(); 105 } 106 107 // 108 // Non-virtual convenience method to set the local time and sync only if needed 109 // 110 void set_and_sync(const sc_core::sc_time& t) 111 { 112 set(t); 113 if (need_sync()) 114 sync(); 115 } 116 117 // 118 // Resets the local time to SC_ZERO_TIME and computes the value of the 119 // next local quantum. This method should be called by an initiator after 120 // a wait because of a synchronization request by a target (TLM_ACCEPTED, 121 // or TLM_UPDATED). 122 // 123 virtual void reset() 124 { 125 m_local_time = sc_core::SC_ZERO_TIME; 126 m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum(); 127 } 128 129 // 130 // Helper function to get the current systemC time, taken the local time 131 // into account. The current systemC time is calculated as the time 132 // returned by sc_time_stamp incremeneted with the time the initiator is 133 // running ahead. 134 // 135 virtual sc_core::sc_time get_current_time() const 136 { 137 return sc_core::sc_time_stamp() + m_local_time; 138 } 139 140 // 141 // Helper functions to get the time the initiator is running ahead of 142 // systenC (local time). This time should be passed to a target in the 143 // nb_transport call 144 // 145 virtual sc_core::sc_time get_local_time() const 146 { 147 return m_local_time; 148 } 149 150 protected: 151 // 152 // Calculate the next local quantum for this initiator. 153 // 154 // The method can be overloaded in a derived object if an initiator wants 155 // to use another local quantum. This derived object should also take the 156 // global quantum into account. It's local quantum should not be set to a 157 // value that is larger than the quantum returned by the 158 // compute_local_quantum of the tlm_global_quantum singleton. 159 // 160 virtual sc_core::sc_time compute_local_quantum() 161 { 162 return tlm::tlm_global_quantum::instance().compute_local_quantum(); 163 } 164 165 protected: 166 sc_core::sc_time m_next_sync_point; 167 sc_core::sc_time m_local_time; 168 }; 169 170} // namespace tlm 171 172#endif 173