SystemC  2.3.2
Accellera SystemC proof-of-concept library
sc_prim_channel.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 /*****************************************************************************
21 
22  sc_prim_channel.h -- Abstract base class of all primitive channel classes.
23 */
33 #ifndef SC_PRIM_CHANNEL_H
34 #define SC_PRIM_CHANNEL_H
35 
36 #include "sysc/kernel/sc_object.h"
37 #include "sysc/kernel/sc_wait.h"
39 
40 namespace sc_core {
41 
49 : public sc_object
50 {
52 
53 public:
54  enum { list_end = 0xdb };
55 public:
56  virtual const char* kind() const
57  { return "sc_prim_channel"; }
58 
59  inline bool update_requested()
60  { return m_update_next_p != (sc_prim_channel*)list_end; }
61 
62  // request the update method to be executed during the update phase
63  inline void request_update();
64 
65  // request the update method to be executed during the update phase
66  // from a process external to the simulator.
67  void async_request_update();
68 
69 protected:
70 
71  // constructors
73  explicit sc_prim_channel( const char* );
74 
75  // destructor
76  virtual ~sc_prim_channel();
77 
78  // the update method (does nothing by default)
79  virtual void update();
80 
81  // called by construction_done (does nothing by default)
82  virtual void before_end_of_elaboration();
83 
84  // called by elaboration_done (does nothing by default)
85  virtual void end_of_elaboration();
86 
87  // called by start_simulation (does nothing by default)
88  virtual void start_of_simulation();
89 
90  // called by simulation_done (does nothing by default)
91  virtual void end_of_simulation();
92 
93  // indicate that this channel is async and could call async_request_update
94  // therefore, the kernel should arrange to suspend rather than exit while
95  // this channel is attached.
96  bool async_attach_suspending();
97  bool async_detach_suspending();
98 
99 protected:
100 
101  // to avoid calling sc_get_curr_simcontext()
102 
103  // static sensitivity for SC_THREADs and SC_CTHREADs
104 
105  void wait()
106  { sc_core::wait( simcontext() ); }
107 
108 
109  // dynamic sensitivity for SC_THREADs and SC_CTHREADs
110 
111  void wait( const sc_event& e )
112  { sc_core::wait( e, simcontext() ); }
113 
114  void wait( const sc_event_or_list& el )
115  { sc_core::wait( el, simcontext() ); }
116 
117  void wait( const sc_event_and_list& el )
118  { sc_core::wait( el, simcontext() ); }
119 
120  void wait( const sc_time& t )
121  { sc_core::wait( t, simcontext() ); }
122 
123  void wait( double v, sc_time_unit tu )
124  { sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); }
125 
126  void wait( const sc_time& t, const sc_event& e )
127  { sc_core::wait( t, e, simcontext() ); }
128 
129  void wait( double v, sc_time_unit tu, const sc_event& e )
130  { sc_core::wait( sc_time( v, tu, simcontext() ), e, simcontext() ); }
131 
132  void wait( const sc_time& t, const sc_event_or_list& el )
133  { sc_core::wait( t, el, simcontext() ); }
134 
135  void wait( double v, sc_time_unit tu, const sc_event_or_list& el )
136  { sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
137 
138  void wait( const sc_time& t, const sc_event_and_list& el )
139  { sc_core::wait( t, el, simcontext() ); }
140 
141  void wait( double v, sc_time_unit tu, const sc_event_and_list& el )
142  { sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
143 
144  void wait( int n )
145  { sc_core::wait( n, simcontext() ); }
146 
147 
148  // static sensitivity for SC_METHODs
149 
151  { sc_core::next_trigger( simcontext() ); }
152 
153 
154  // dynamic sensitivity for SC_METHODs
155 
156  void next_trigger( const sc_event& e )
157  { sc_core::next_trigger( e, simcontext() ); }
158 
159  void next_trigger( const sc_event_or_list& el )
160  { sc_core::next_trigger( el, simcontext() ); }
161 
162  void next_trigger( const sc_event_and_list& el )
163  { sc_core::next_trigger( el, simcontext() ); }
164 
165  void next_trigger( const sc_time& t )
166  { sc_core::next_trigger( t, simcontext() ); }
167 
168  void next_trigger( double v, sc_time_unit tu )
169  {sc_core::next_trigger( sc_time( v, tu, simcontext() ), simcontext() );}
170 
171  void next_trigger( const sc_time& t, const sc_event& e )
172  { sc_core::next_trigger( t, e, simcontext() ); }
173 
174  void next_trigger( double v, sc_time_unit tu, const sc_event& e )
176  sc_time( v, tu, simcontext() ), e, simcontext() ); }
177 
178  void next_trigger( const sc_time& t, const sc_event_or_list& el )
179  { sc_core::next_trigger( t, el, simcontext() ); }
180 
181  void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el )
183  sc_time( v, tu, simcontext() ), el, simcontext() ); }
184 
185  void next_trigger( const sc_time& t, const sc_event_and_list& el )
186  { sc_core::next_trigger( t, el, simcontext() ); }
187 
188  void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el )
190  sc_time( v, tu, simcontext() ), el, simcontext() ); }
191 
192 
193  // for SC_METHODs and SC_THREADs and SC_CTHREADs
194 
195  bool timed_out()
196  { return sc_core::timed_out( simcontext() ); }
197 
198 
199 #if 0 // @@@@####
200  // delta count maintenance
201  sc_dt::uint64 delta_count()
202  { return simcontext()->m_delta_count; }
203 #endif
204 
205 private:
206 
207  // called during the update phase of a delta cycle (if requested)
208  void perform_update();
209 
210  // called when construction is done
211  void construction_done();
212 
213  // called when elaboration is done
214  void elaboration_done();
215 
216  // called before simulation starts
217  void start_simulation();
218 
219  // called after simulation ends
220  void simulation_done();
221 
222  // disabled
224  sc_prim_channel& operator = ( const sc_prim_channel& );
225 
226 private:
227 
228  sc_prim_channel_registry* m_registry; // Update list manager.
229  sc_prim_channel* m_update_next_p; // Next entry in update list.
230 };
231 
232 
241 {
242  friend class sc_simcontext;
243 
244 public:
245 
246  void insert( sc_prim_channel& );
247  void remove( sc_prim_channel& );
248 
249 
250  int size() const
251  { return static_cast<int>(m_prim_channel_vec.size()); }
252 
253  inline void request_update( sc_prim_channel& );
254  void async_request_update( sc_prim_channel& );
255 
256  bool pending_updates() const
257  {
258  return m_update_list_p != (sc_prim_channel*)sc_prim_channel::list_end
259  || pending_async_updates();
260  }
261 
262  bool pending_async_updates() const;
263 
264  // synchronization with attached async suspending channels
265  // - potentially blocks the current thread, if no explicitly
266  // attached async channels have posted updates, yet
267  // - returns true, if and only if there are NO pending synchronous
268  // updates after resuming from the external synchronization
269  bool async_suspend();
270 
271  // (un)register a channel as being asynchronous
272  // - presence of asynchronous channels leads async_suspend() to
273  // block until any external async updates have been received
274  // (instead of exiting the simulation upon starvation)
275  bool async_attach_suspending(sc_prim_channel&);
276  bool async_detach_suspending(sc_prim_channel&);
277 
278 private:
279 
280  // constructor
281  explicit sc_prim_channel_registry( sc_simcontext& simc_ );
282 
283  // destructor
285 
286  // called during the update phase of a delta cycle
287  void perform_update();
288 
289  // called when construction is done
290  bool construction_done();
291 
292  // called when elaboration is done
293  void elaboration_done();
294 
295  // called before simulation starts
296  void start_simulation();
297 
298  // called after simulation ends
299  void simulation_done();
300 
301  // disabled
304  sc_prim_channel_registry& operator = ( const sc_prim_channel_registry& );
305 
306 private:
307  class async_update_list;
308 
309  async_update_list* m_async_update_list_p; // external updates.
310  int m_construction_done; // # of constructs.
311  std::vector<sc_prim_channel*> m_prim_channel_vec; // existing channels.
312  sc_simcontext* m_simc; // simulator context.
313  sc_prim_channel* m_update_list_p; // internal updates.
314 };
315 
316 
317 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
318 
326 inline
327 void
329 {
330  prim_channel_.m_update_next_p = m_update_list_p;
331  m_update_list_p = &prim_channel_;
332 }
333 
340 // request the update method (to be executed during the update phase)
341 
342 inline
343 void
345 {
346  if( ! m_update_next_p ) {
347  m_registry->request_update( *this );
348  }
349 }
350 
351 // request the update method from external to the simulator (to be executed
352 // during the update phase)
353 
354 inline
355 void
357 {
358  m_registry->async_request_update(*this);
359 }
360 
361 inline
362 bool
364 {
365  return m_registry->async_attach_suspending(*this);
366 }
367 
368 inline
369 bool
371 {
372  return m_registry->async_detach_suspending(*this);
373 }
374 
375 
376 // called during the update phase of a delta cycle (if requested)
377 
378 inline
379 void
380 sc_prim_channel::perform_update()
381 {
382  update();
383  m_update_next_p = 0;
384 }
385 
386 
387 } // namespace sc_core
388 
389 
390 /*****************************************************************************
391 
392  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
393  changes you are making here.
394 
395  Name, Affiliation, Date: Andy Goodrich, Forte,
396  Bishnupriya Bhattacharya, Cadence Design Systems,
397  25 August, 2003
398  Description of Modification: phase callbacks
399 
400  *****************************************************************************/
401 //$Log: sc_prim_channel.h,v $
402 //Revision 1.10 2011/08/26 21:38:32 acg
403 // Philipp A. Hartmann: removed unused switch m_construction_done.
404 //
405 //Revision 1.9 2011/08/07 19:08:01 acg
406 // Andy Goodrich: moved logs to end of file so line number synching works
407 // better between versions.
408 //
409 //Revision 1.8 2011/05/09 04:07:37 acg
410 // Philipp A. Hartmann:
411 // (1) Restore hierarchy in all phase callbacks.
412 // (2) Ensure calls to before_end_of_elaboration.
413 //
414 //Revision 1.7 2011/05/05 17:44:01 acg
415 // Philip A. Hartmann: change in the name of pending_async_updates.
416 //
417 //Revision 1.6 2011/04/19 15:03:48 acg
418 // Philipp A. Hartmann: remove ASYNC_UPDATE preprocessor check from header.
419 //
420 //Revision 1.5 2011/04/19 02:36:26 acg
421 // Philipp A. Hartmann: new aysnc_update and mutex support.
422 //
423 //Revision 1.4 2011/04/05 20:48:09 acg
424 // Andy Goodrich: changes to make sure that event(), posedge() and negedge()
425 // only return true if the clock has not moved.
426 //
427 //Revision 1.3 2011/02/18 20:23:45 acg
428 // Andy Goodrich: Copyright update.
429 //
430 //Revision 1.2 2011/01/20 16:52:15 acg
431 // Andy Goodrich: changes for IEEE 1666 2011.
432 //
433 //Revision 1.1.1.1 2006/12/15 20:20:04 acg
434 //SystemC 2.3
435 //
436 //Revision 1.3 2006/05/08 17:52:47 acg
437 // Andy Goodrich:
438 // (1) added David Long's forward declarations for friend functions,
439 // methods, and operators to keep the Microsoft compiler happy.
440 // (2) Added delta_count() method to sc_prim_channel for use by
441 // sc_signal so that the friend declaration in sc_simcontext.h
442 // can be for a non-templated class (i.e., sc_prim_channel.)
443 //
444 //Revision 1.2 2006/01/03 23:18:26 acg
445 //Changed copyright to include 2006.
446 //
447 //Revision 1.1.1.1 2005/12/19 23:16:43 acg
448 //First check in of SystemC 2.1 into its own archive.
449 //
450 //Revision 1.10 2005/07/30 03:44:11 acg
451 //Changes from 2.1.
452 //
453 //Revision 1.9 2005/06/10 22:43:55 acg
454 //Added CVS change log annotation.
455 
456 #endif
457 
458 // Taf!
void next_trigger(double v, sc_time_unit tu, const sc_event_or_list &el)
void wait(double v, sc_time_unit tu, const sc_event &e)
void wait(const sc_time &t, const sc_event_and_list &el)
void wait(const sc_event &e)
void next_trigger(const sc_time &t, const sc_event &e)
void request_update(sc_prim_channel &)
void next_trigger(const sc_time &t)
SC_API void next_trigger(sc_simcontext *)
Abstract base class of all SystemC `simulation&#39; objects.
Definition: sc_object.h:61
AND list of events.
Definition: sc_event.h:189
Wait() and related functions.
The event class.
Definition: sc_event.h:256
void wait(const sc_time &t)
virtual const char * kind() const
uint64_t uint64
Definition: sc_nbdefs.h:189
void wait(const sc_event_and_list &el)
Registry for all primitive channels.
void next_trigger(const sc_event_or_list &el)
Wait() and related functions for SC_CTHREADs.
void next_trigger(double v, sc_time_unit tu)
void wait(const sc_time &t, const sc_event &e)
void wait(double v, sc_time_unit tu, const sc_event_and_list &el)
void wait(const sc_time &t, const sc_event_or_list &el)
Abstract base class of all SystemC `simulation&#39; objects.
void wait(double v, sc_time_unit tu)
SC_API bool timed_out(sc_simcontext *)
The simulation context.
void next_trigger(const sc_event &e)
void wait(double v, sc_time_unit tu, const sc_event_or_list &el)
The time class.
Definition: sc_time.h:82
void next_trigger(const sc_time &t, const sc_event_and_list &el)
void next_trigger(const sc_time &t, const sc_event_or_list &el)
void wait(const sc_event_or_list &el)
void next_trigger(double v, sc_time_unit tu, const sc_event &e)
OR list of events.
Definition: sc_event.h:224
void next_trigger(double v, sc_time_unit tu, const sc_event_and_list &el)
void next_trigger(const sc_event_and_list &el)
Abstract base class of all primitive channel classes.
#define SC_API
Definition: sc_cmnhdr.h:168
sc_time_unit
Enumeration of time units.
Definition: sc_time.h:64
void SC_API wait(int, sc_simcontext *)