tlm_quantumkeeper.h (13516:315f10e2567b) tlm_quantumkeeper.h (13586:008fe87c1ad4)
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
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>
23#include "../core/sc_time.hh"
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__ */
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__ */