00001 /***************************************************************************** 00002 00003 The following code is derived, directly or indirectly, from the SystemC 00004 source code Copyright (c) 1996-2008 by all Contributors. 00005 All Rights reserved. 00006 00007 The contents of this file are subject to the restrictions and limitations 00008 set forth in the SystemC Open Source License Version 3.0 (the "License"); 00009 You may not use this file except in compliance with such restrictions and 00010 limitations. You may obtain instructions on how to receive a copy of the 00011 License at http://www.systemc.org/. Software distributed by Contributors 00012 under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF 00013 ANY KIND, either express or implied. See the License for the specific 00014 language governing rights and limitations under the License. 00015 00016 *****************************************************************************/ 00017 00018 #ifndef __TLM_GLOBAL_QUANTUM_H__ 00019 #define __TLM_GLOBAL_QUANTUM_H__ 00020 00021 #include <systemc> 00022 00023 namespace tlm { 00024 00025 namespace tlm_qk_internal { 00026 00027 // 00028 // tlm_global_quantum class 00029 // 00030 // The global quantum is the maximum time an initiator can run ahead of 00031 // systemC time. All initiators should synchronize on timingpoints that 00032 // are multiples of the global quantum value. 00033 // 00034 // sc_set_time_resolution can only be called before the first 00035 // sc_time object is created. This means that after setting the 00036 // global quantum it will not be possible to call sc_set_time_resolution. 00037 // If sc_set_time_resolution must be called this must be done before 00038 // the global quantum is set. 00039 // 00040 // NOTE: 00041 // The templated class tlm::tlm_qk_internal::tlm_global_quantum<Dummy> is 00042 // an artifact of the implementation and not part of the core TLM standard. 00043 // It should never be used directly, instead the class 00044 // tlm::tlm_global_quantum should be used. 00045 // 00046 // The dummy template parameter is introduced to make it possible to 00047 // initialize the static member (m_instance) in the headerfile. This 00048 // is only possible for template classes, otherwise the static member must 00049 // be initialized in a source file. 00050 // 00051 template <typename Dummy> 00052 class tlm_global_quantum 00053 { 00054 public: 00055 // 00056 // Returns a reference to the tlm_global_quantum singleton 00057 // 00058 static tlm_global_quantum& instance() 00059 { 00060 if (!m_instance) { 00061 m_instance = new tlm_global_quantum; 00062 } 00063 return *m_instance; 00064 } 00065 00066 public: 00067 virtual ‾tlm_global_quantum() 00068 { 00069 m_instance = 0; 00070 } 00071 00072 // 00073 // Setter/getter for the global quantum 00074 // 00075 void set(const sc_core::sc_time& t) 00076 { 00077 m_global_quantum = t; 00078 } 00079 00080 const sc_core::sc_time& get() const 00081 { 00082 return m_global_quantum; 00083 } 00084 00085 // 00086 // This function will calculate the maximum value for the next local 00087 // quantum for an initiator. All initiators should synchronize on 00088 // integer multiples of the global quantum value. The value for the 00089 // local quantum of an initiator can be smaller, but should never be 00090 // greater than the value returned by this method. 00091 // 00092 sc_core::sc_time compute_local_quantum() 00093 { 00094 if (m_global_quantum != sc_core::SC_ZERO_TIME) { 00095 const sc_dt::uint64 current = sc_core::sc_time_stamp().value(); 00096 const sc_dt::uint64 g_quant = m_global_quantum.value(); 00097 const sc_dt::uint64 tmp = (current/g_quant+sc_dt::uint64(1)) * g_quant; 00098 const sc_core::sc_time remainder = sc_core::sc_time(tmp - current, 00099 false); 00100 return remainder; 00101 00102 } else { 00103 return sc_core::SC_ZERO_TIME; 00104 } 00105 } 00106 00107 protected: 00108 tlm_global_quantum() : m_global_quantum(sc_core::SC_ZERO_TIME) 00109 { 00110 } 00111 00112 protected: 00113 static tlm_global_quantum* m_instance; 00114 sc_core::sc_time m_global_quantum; 00115 }; 00116 00117 template <typename Dummy> 00118 tlm_global_quantum<Dummy>* tlm_global_quantum<Dummy>::m_instance = 0; 00119 00120 struct tlm_dummy {}; 00121 00122 } // namespace tlm_qk_internal 00123 00124 typedef tlm_qk_internal::tlm_global_quantum<tlm_qk_internal::tlm_dummy> tlm_global_quantum; 00125 00126 } // namespace tlm 00127 00128 #endif