gem5  v20.1.0.0
peq_with_cb_and_phase.h
Go to the documentation of this file.
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_PEQ_WITH_CB_AND_PHASE_H__
21 #define __SYSTEMC_EXT_TLM_UTILS_PEQ_WITH_CB_AND_PHASE_H__
22 
23 #include <vector>
24 
25 #include "../core/sc_main.hh"
26 #include "../core/sc_object.hh"
27 #include "../core/sc_spawn.hh"
28 #include "../core/sc_time.hh"
29 #include "../dt/int/sc_nbdefs.hh"
30 #include "../tlm_core/2/interfaces/fw_bw_ifs.hh"
31 
32 namespace tlm_utils
33 {
34 
35 template <typename PAYLOAD>
36 class time_ordered_list
37 {
38  public:
39  struct element
40  {
41  struct element *next;
42  PAYLOAD p;
46  p(p), t(t), d(d)
47  {}
48  element() {}
49  };
50 
51  element *nill;
52  element *empties;
54  unsigned int size;
55 
56  time_ordered_list() : nill(new element()), empties(NULL),
57  list(nill), size(0)
58  {}
59 
61  {
62  reset();
63  while (empties) {
64  struct element *e = empties->next;
65  delete empties;
66  empties = e;
67  }
68  delete nill;
69  }
70 
71  void
72  reset()
73  {
74  while (size) {
75  delete_top();
76  }
77  }
78 
79  void
80  insert(const PAYLOAD &p, sc_core::sc_time t)
81  {
82  if (!empties) {
83  empties = new struct element();
84  empties->next=NULL;
85  }
86 
87  struct element *e = empties;
89  e->p = p;
90  e->t = t;
92 
93  struct element *ancestor = nill;
94  struct element *iterator = list;
95  while (iterator != nill && iterator->t <= t) {
96  ancestor = iterator;
97  iterator = iterator->next;
98  }
99  if (ancestor == nill) {
100  e->next = list;
101  list = e;
102  } else {
103  e->next = iterator;
104  ancestor->next = e;
105  }
106  size++;
107  }
108 
109  void
110  delete_top()
111  {
112  if (list != nill) {
113  struct element *e = list;
115  e->next = empties;
116  empties = e;
117  size--;
118  }
119  }
120 
121  unsigned int get_size() { return size; }
122  PAYLOAD &top() { return list->p; }
123  sc_core::sc_time top_time() { return list->t; }
124  sc_dt::uint64 &top_delta() { return list->d; }
125  sc_core::sc_time next_time() { return list->next->t; }
126 };
127 
128 //---------------------------------------------------------------------------
133 //---------------------------------------------------------------------------
134 template<typename OWNER, typename TYPES=tlm::tlm_base_protocol_types>
135 class peq_with_cb_and_phase : public sc_core::sc_object
136 {
137  typedef typename TYPES::tlm_payload_type tlm_payload_type;
138  typedef typename TYPES::tlm_phase_type tlm_phase_type;
140  typedef void (OWNER::*cb)(tlm_payload_type &, const tlm_phase_type &);
141 
142  class delta_list
143  {
144  public:
145  delta_list()
146  {
147  reset();
148  entries.resize(100);
149  }
150 
151  inline void
152  insert(const PAYLOAD &p)
153  {
154  if (size==entries.size()) {
155  entries.resize(entries.size() * 2);
156  }
157  entries[size++] = p;
158  }
159 
160  inline PAYLOAD &get() { return entries[out++]; }
161  inline bool next() { return out < size; }
162  inline void
163  reset()
164  {
165  size=0;
166  out=0;
167  }
168 
169  public:
170  unsigned int size;
171 
172  private:
174  unsigned int out;
175  };
176 
177  public:
178  peq_with_cb_and_phase(OWNER *_owner, cb _cb) :
180  "peq_with_cb_and_phase")),
181  m_owner(_owner), m_cb(_cb)
182  {
184  opts.spawn_method();
185  opts.set_sensitivity(&m_e);
186  opts.dont_initialize();
188  sc_core::sc_gen_unique_name("fec"), &opts);
189  }
190 
191  peq_with_cb_and_phase(const char *_name, OWNER *_owner, cb _cb) :
192  sc_core::sc_object(_name), m_owner(_owner), m_cb(_cb)
193  {
195  opts.spawn_method();
196  opts.set_sensitivity(&m_e);
197  opts.dont_initialize();
199  sc_core::sc_gen_unique_name("fec"), &opts);
200  }
201 
203 
204  void
206  const sc_core::sc_time &when)
207  {
208  if (when == sc_core::SC_ZERO_TIME) {
209  if (sc_core::sc_delta_count() & (sc_dt::uint64)0x1) {
210  // Uneven delta cycle so delta delay is for even cycle.
212  } else {
213  // Even delta cycle so delta delay is for uneven delta.
215  }
217  } else {
218  m_ppq.insert(PAYLOAD(&t, p), when + sc_core::sc_time_stamp());
219  // Note, this will only overwrite the "newest" event.
220  m_e.notify(when);
221  }
222  }
223 
224  void
226  {
228  m_e.notify(); // Immediate notification.
229  }
230 
231  // Cancel all events from the event queue.
232  void
233  cancel_all()
234  {
235  m_ppq.reset();
239  m_e.cancel();
240  }
241 
242  private:
243  void
244  fec()
245  {
246  // Immediate yield notifications.
247  while (m_immediate_yield.next()) {
248  PAYLOAD &tmp = m_immediate_yield.get();
249  (m_owner->*m_cb)(*tmp.first, tmp.second);
250  }
252 
253  // Delta notifications.
254  if (sc_core::sc_delta_count() & (sc_dt::uint64)0x1) {
255  // Uneven delta so put out all payloads for uneven delta.
256  while (m_uneven_delta.next()) {
257  PAYLOAD &tmp = m_uneven_delta.get();
258  (m_owner->*m_cb)(*tmp.first, tmp.second);
259  }
263  } else {
264  while (m_even_delta.next()) {
265  PAYLOAD &tmp = m_even_delta.get();
266  (m_owner->*m_cb)(*tmp.first, tmp.second);
267  }
269  if (m_uneven_delta.size)
271  }
272  if (!m_ppq.get_size())
273  return; // There were only delta notification.
274 
275  // Timed notifications.
277  sc_core::sc_time top = m_ppq.top_time();
278 
279  while (m_ppq.get_size() && top == now) {
280  // Push all active ones into target.
281  PAYLOAD &tmp = m_ppq.top();
282  (m_owner->*m_cb)(*tmp.first, tmp.second);
283  m_ppq.delete_top();
284  top = m_ppq.top_time();
285  }
286  if (m_ppq.get_size()) {
287  m_e.notify(top - now);
288  }
289  }
290 
291  OWNER *m_owner;
292  cb m_cb;
293 
294  time_ordered_list<PAYLOAD> m_ppq;
295  delta_list m_uneven_delta;
296  delta_list m_even_delta;
297  delta_list m_immediate_yield;
298 
299  sc_core::sc_event m_e; // Default event.
300 };
301 
302 } // namespace tlm_utils
303 
304 #endif /* __SYSTEMC_EXT_TLM_UTILS_PEQ_WITH_CB_AND_PHASE_H__ */
tlm_utils::time_ordered_list::insert
void insert(const PAYLOAD &p, sc_core::sc_time t)
Definition: peq_with_cb_and_phase.h:114
tlm_utils::time_ordered_list::element::t
sc_core::sc_time t
Definition: peq_with_cb_and_phase.h:94
tlm_utils::time_ordered_list::empties
element * empties
Definition: peq_with_cb_and_phase.h:86
tlm_utils::peq_with_cb_and_phase::m_e
sc_core::sc_event m_e
Definition: peq_with_cb_and_phase.h:316
sc_core::sc_spawn_options::set_sensitivity
void set_sensitivity(const sc_event *)
Definition: sc_spawn.cc:146
sc_core
Definition: messages.cc:31
tlm_utils::peq_with_cb_and_phase::PAYLOAD
std::pair< tlm_payload_type *, tlm_phase_type > PAYLOAD
Definition: peq_with_cb_and_phase.h:156
sc_core::sc_spawn_options::dont_initialize
void dont_initialize()
Definition: sc_spawn.cc:133
tlm_utils::peq_with_cb_and_phase::cb
void(OWNER::* cb)(tlm_payload_type &, const tlm_phase_type &)
Definition: peq_with_cb_and_phase.h:157
sc_core::SC_ZERO_TIME
const sc_time SC_ZERO_TIME
Definition: sc_time.cc:290
tlm_utils::time_ordered_list::top_time
sc_core::sc_time top_time()
Definition: peq_with_cb_and_phase.h:157
top
Definition: test.h:61
tlm_utils::peq_with_cb_and_phase::m_even_delta
delta_list m_even_delta
Definition: peq_with_cb_and_phase.h:313
std::vector
STL vector class.
Definition: stl.hh:37
tlm_utils::time_ordered_list::element::d
sc_dt::uint64 d
Definition: peq_with_cb_and_phase.h:95
tlm_utils::time_ordered_list::element::p
PAYLOAD p
Definition: peq_with_cb_and_phase.h:93
tlm_utils::peq_with_cb_and_phase::m_uneven_delta
delta_list m_uneven_delta
Definition: peq_with_cb_and_phase.h:312
tlm_utils::time_ordered_list::get_size
unsigned int get_size()
Definition: peq_with_cb_and_phase.h:155
tlm_utils::time_ordered_list::time_ordered_list
time_ordered_list()
Definition: peq_with_cb_and_phase.h:90
tlm_utils::peq_with_cb_and_phase::delta_list::delta_list
delta_list()
Definition: peq_with_cb_and_phase.h:162
tlm_utils::time_ordered_list::reset
void reset()
Definition: peq_with_cb_and_phase.h:106
tlm_utils::peq_with_cb_and_phase::tlm_payload_type
TYPES::tlm_payload_type tlm_payload_type
Definition: peq_with_cb_and_phase.h:154
tlm_utils::time_ordered_list::element
Definition: peq_with_cb_and_phase.h:73
tlm_utils::peq_with_cb_and_phase::delta_list::get
PAYLOAD & get()
Definition: peq_with_cb_and_phase.h:177
sc_dt::uint64
uint64_t uint64
Definition: sc_nbdefs.hh:206
tlm_utils::peq_with_cb_and_phase::tlm_phase_type
TYPES::tlm_phase_type tlm_phase_type
Definition: peq_with_cb_and_phase.h:155
tlm_utils::peq_with_cb_and_phase::peq_with_cb_and_phase
peq_with_cb_and_phase(OWNER *_owner, cb _cb)
Definition: peq_with_cb_and_phase.h:195
sc_core::sc_event
Definition: sc_event.hh:169
tlm_utils::peq_with_cb_and_phase::cancel_all
void cancel_all()
Definition: peq_with_cb_and_phase.h:250
sc_core::sc_spawn_options::spawn_method
void spawn_method()
Definition: sc_spawn.cc:127
sc_core::sc_time
Definition: sc_time.hh:49
tlm_utils::time_ordered_list::list
element * list
Definition: peq_with_cb_and_phase.h:87
tlm_utils::time_ordered_list::nill
element * nill
Definition: peq_with_cb_and_phase.h:85
tlm_utils::peq_with_cb_and_phase::delta_list::out
unsigned int out
Definition: peq_with_cb_and_phase.h:191
tlm_utils::peq_with_cb_and_phase::delta_list::next
bool next()
Definition: peq_with_cb_and_phase.h:178
sc_core::sc_gen_unique_name
const char * sc_gen_unique_name(const char *seed)
Definition: sc_module.cc:820
tlm_utils::time_ordered_list::element::element
element()
Definition: peq_with_cb_and_phase.h:99
std::pair
STL pair class.
Definition: stl.hh:58
sc_core::sc_object
Definition: sc_object.hh:50
tlm_utils::time_ordered_list::delete_top
void delete_top()
Definition: peq_with_cb_and_phase.h:144
sc_core::sc_event::notify
void notify()
Definition: sc_event.cc:337
ArmISA::e
Bitfield< 9 > e
Definition: miscregs_types.hh:61
tlm_utils
Definition: convenience_socket_bases.h:29
tlm_utils::peq_with_cb_and_phase::delta_list::size
unsigned int size
Definition: peq_with_cb_and_phase.h:187
tlm_utils::time_ordered_list::top_delta
sc_dt::uint64 & top_delta()
Definition: peq_with_cb_and_phase.h:158
tlm_utils::time_ordered_list::next_time
sc_core::sc_time next_time()
Definition: peq_with_cb_and_phase.h:159
tlm_utils::time_ordered_list::top
PAYLOAD & top()
Definition: peq_with_cb_and_phase.h:156
sc_core::sc_delta_count
sc_dt::uint64 sc_delta_count()
Definition: sc_main.cc:136
sc_core::sc_event::cancel
void cancel()
Definition: sc_event.cc:340
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
tlm_utils::time_ordered_list::element::next
struct element * next
Definition: peq_with_cb_and_phase.h:92
tlm_utils::peq_with_cb_and_phase::delta_list::insert
void insert(const PAYLOAD &p)
Definition: peq_with_cb_and_phase.h:169
sc_core::sc_object::sc_object
sc_object()
Definition: sc_object.cc:133
tlm_utils::time_ordered_list::~time_ordered_list
~time_ordered_list()
Definition: peq_with_cb_and_phase.h:94
tlm_utils::peq_with_cb_and_phase::~peq_with_cb_and_phase
~peq_with_cb_and_phase()
Definition: peq_with_cb_and_phase.h:219
tlm_utils::peq_with_cb_and_phase::delta_list::reset
void reset()
Definition: peq_with_cb_and_phase.h:180
tlm_utils::peq_with_cb_and_phase::fec
void fec()
Definition: peq_with_cb_and_phase.h:261
sc_core::sc_spawn
sc_process_handle sc_spawn(T object, const char *name_p=nullptr, const sc_spawn_options *opt_p=nullptr)
Definition: sc_spawn.hh:154
sc_core::sc_spawn_options
Definition: sc_spawn.hh:93
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
tlm_utils::peq_with_cb_and_phase::notify
void notify(tlm_payload_type &t, const tlm_phase_type &p, const sc_core::sc_time &when)
Definition: peq_with_cb_and_phase.h:222
tlm_utils::peq_with_cb_and_phase::m_immediate_yield
delta_list m_immediate_yield
Definition: peq_with_cb_and_phase.h:314
tlm_utils::peq_with_cb_and_phase::m_owner
OWNER * m_owner
Definition: peq_with_cb_and_phase.h:308
tlm_utils::peq_with_cb_and_phase::m_cb
cb m_cb
Definition: peq_with_cb_and_phase.h:309
sc_core::sc_bind
auto sc_bind(F &&f, Args &&...args) -> decltype(std::bind(std::forward< F >(f), std::forward< Args >(args)...))
Definition: sc_spawn.hh:198
sc_core::sc_time_stamp
const sc_time & sc_time_stamp()
Definition: sc_main.cc:128
tlm_utils::time_ordered_list::size
unsigned int size
Definition: peq_with_cb_and_phase.h:88
tlm_utils::peq_with_cb_and_phase::m_ppq
time_ordered_list< PAYLOAD > m_ppq
Definition: peq_with_cb_and_phase.h:311
tlm_utils::peq_with_cb_and_phase::delta_list::entries
std::vector< PAYLOAD > entries
Definition: peq_with_cb_and_phase.h:190

Generated on Wed Sep 30 2020 14:02:16 for gem5 by doxygen 1.8.17